Description
Describe the bug
Testing component with Task.Run
inside of async Task OnInitializedAsync
results in intermittent test failures. When running the test by itself, it will always succeed. When running with all other tests in the class, certain tests will intermittently fail. It's important to note below is an example of what we see causing, we have 14 tests inside our tests class, verifying different aspects of functionality. The tests themselves and the component are more robust, and I can added in a more detailed example if need be. We've also attempted to use both WaitForState
and WaitForAssertion
in both cases, neither results in the expected behavior. Additionally, adding timespans of upwards of 15 seconds has not fixed the behavior either.
I assume this has something to do with trying to run multiple threads with the tests and some asynchronous action locking the completion of the task.
I've verified:
- Removing all but on test will result in the single test passing every time
- Removing the
_ = Task.Run
and doing all that work inside the initialization results in the tests passing every time. - Running the tests inside of the IDE (Rider) has the same results as running through the cli with the
dotnet tests
command.
Example:
Testing this component:
@if(loading)
{
<div class="is-loading">LOADING ICON</div>
}
else
{
<div class="assert-data">DATA HAS LOADED</div>
}
@code{
bool loading;
protected override async Task OnInitializedAsync()
{
loading = true;
...async work being done
_ = Task.Run(async () => {
...async work to be done on separate thread
loading = false;
await InvokeAsync(StateHasChanged);
});
}
}
With this test:
[Fact(DisplayName = "Check really important functionality")]
public void Test()
{
var subject = RenderComponent<MyTestComponent>();
subject.WaitForState(() => _subject.Find(".assert-data").TextContent == "DATA HAS LOADED");
subject.WaitForAssertion(() => _subject.Find(".assert-data").TextContent.Should.Be("DATA HAS LOADED"));
}
Results in this output:
Bunit.Extensions.WaitForHelpers.WaitForFailedException : The assertion did not pass within the timeout period. Check count: 6. Component render count: 9. Total render count: 9.
Expected behavior:
I expect the test passes every single time, whether ran individually or ran with all other tests.
Version info:
- bUnit version: 1.28.9 (saw the same behavior in 1.27.17)
- .NET Runtime and Blazor version: .net 8
- OS type and version: windows 11
Additional context:
Using XUnit, FluentAssertions, and MOQ.