question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

FragmentContainer was not found in async test

See original GitHub issue

Describe the bug

I have a relatively simple component that just renders different content depending on the state of a Task. The code of both component and test is very similar to the async example except that instead of awaiting the task on init I’m using task.ContinueWith(...) => InvokeAsync(StateHasChanged) and using the razor test syntax.

When using bUnit 1.16.2 and not using WaitForAssertion, the tests almost always pass. (I did very very rarely observe the same waiting failure as below.) When using later versions of bUnit, the tests will more frequently intermittently fail (showing the waiting content rather than the done content). When I tried adding WaitForAssertion (in 1.16.2) it started instead failing with:

Bunit.Extensions.WaitForHelpers.WaitForFailedException : The assertion did not pass within the timeout period. Check count: 2. Component render count: 2. Total render count: 5.
  ----> Bunit.Rendering.ComponentNotFoundException : A component of type FragmentContainer was not found in the render tree.
   at Bunit.RenderedFragmentWaitForHelperExtensions.WaitForAssertion(IRenderedFragmentBase renderedFragment, Action assertion, Nullable`1 timeout) in /_/src/bunit.core/Extensions/WaitForHelpers/RenderedFragmentWaitForHelperExtensions.cs:line 72

I haven’t been able to replicate precisely this behaviour in a MCVE test, but what I did manage to reproduce is described below.

(Oddly, the MCVE code always fails (with waiting content, not the exception) when not using WaitForAssertion. While not exactly surprising due to async, it’s odd that it’s different; though it’s likely that this is due to the real component being a bit more complex.)

Example: Testing this component:

@if (Task != null)
{
    @if (Task.IsCompleted)
    {
        <span>done</span>
    }
    else
    {
        <span>waiting</span>
    }
}

@code {

    [Parameter] public Task? Task { get; set; }

    private Task? _RegisteredTask;

    protected override void OnParametersSet()
    {
        var task = Task;
        if (task != _RegisteredTask)
        {
            _RegisteredTask = task;

            _ = task?.ContinueWith((t, o) =>
            {
                if (t == Task)
                {
                    _ = InvokeAsync(StateHasChanged);
                }
            }, null);
        }

        base.OnParametersSet();
    }

}

With this test:

@using NUnit.Framework
@using Bunit
@*@inherits Bunit.TestContext*@
@inherits BunitTestContext  /* this uses TestContextWrapper */
@code {

    [Test]
    public void Cancel1()
    {
        var tcs = new TaskCompletionSource();

        using var cut = Render(@<MyComponent Task="@tcs.Task"/>);

        cut.MarkupMatches(@<span>waiting</span>);

        tcs.SetCanceled();

        cut.WaitForAssertion(() => cut.MarkupMatches(@<span>done</span>));
    }

    [Test]
    public void Cancel2()
    {
        var tcs = new TaskCompletionSource();

        using var cut = Render(@<MyComponent Task="@tcs.Task"/>);

        cut.MarkupMatches(@<span>waiting</span>);

        tcs.SetCanceled();

        cut.WaitForAssertion(() => cut.MarkupMatches(@<span>done</span>));
    }

    [Test]
    public void Cancel3()
    {
        var tcs = new TaskCompletionSource();

        using var cut = Render(@<MyComponent Task="@tcs.Task"/>);

        cut.MarkupMatches(@<span>waiting</span>);

        tcs.SetCanceled();

        cut.WaitForAssertion(() => cut.MarkupMatches(@<span>done</span>));
    }

}

(Note that this is three identical copies of the same test.)

Expected behavior:

All tests should pass.

Actual behavior:

The first test always passes. The other two tests intermittently fail with the exception above.

If I run the tests in the debugger (without stopping on any breakpoints or exceptions), all tests pass.

Version info:

  • bUnit version: 1.21.9
  • Blazor version: 6.0.18
  • .NET Runtime version: 6.0.405 (SDK 7.0.102)
  • OS type and version: Windows 10, VS2022

Issue Analytics

  • State:closed
  • Created 3 months ago
  • Comments:40 (17 by maintainers)

github_iconTop GitHub Comments

1reaction
uecasmcommented, Jul 18, 2023

Yes, it’s the same FragmentContainer exception.

1reaction
linkdotnetcommented, Jul 11, 2023

I try to find some time to provide a fix

Read more comments on GitHub >

github_iconTop Results From Across the Web

Spring @Async - no data found in integration test
I'm trying to unit (integration) test a method annotated with Spring's @Async. The test sets up some data in in-memory h2 database, then...
Read more >
No view found for id 0x9 (unknown) for fragment ...
Description I have a ListView on MasterPage detail public class MainPage : ContentPage { private bool _isRefreshExecuted; private readonly ...
Read more >
Test your fragments
Drive the fragment to a new state ... In your app's UI tests, it's usually sufficient to launch the fragment under test and...
Read more >
Android. Navigate from custom view renderer to another ...
I make a test about navigating the page in the custom renderer, it is working.
Read more >
Mixing async/await code with waitForExpectations in tests ...
I've encountered a problem with awaiting expectations in XCTestCase when testing async code. I want to test code that is supposed to execute ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found