Skip to content

Components render too many times with SetParametersAndRender #1119

@Jcparkyn

Description

@Jcparkyn

In certain cases, calls to StateHasChanged behave differently in BUnit than in regular Blazor WASM (I haven't tested server-side, but I'd expect it to have the same problem). This means that components in BUnit render too many times, and RenderCount values in BUnit are often higher than they should actually be. I have observed this when using SetParametersAndRender, but I'm not sure if there are other scenarios where this happens.

This is a problem in my case, because I care a lot about the number of renders, but I have no way to reliably assert the RenderCount in tests.

Example:
Testing this component:

<p>Hello world!</p>

@{
    Console.WriteLine("Rendering RenderCountDemo");
}

@code {

    [Parameter]
    public int X { get; set; }

    protected override void OnParametersSet()
    {
        base.OnParametersSet();
        StateHasChanged();
        StateHasChanged();
        StateHasChanged();
    }
}

With this test:

[Fact]
public void Should_have_correct_RenderCount()
{
    var cut = Render<RenderCountDemo>(@<RenderCountDemo X="1" />);
    cut.SetParametersAndRender(); // This should only trigger one additional render.
    cut.RenderCount.Should().Be(2);
}

Results in this output:

Expected cut.RenderCount to be 2, but found 5

Expected behavior:

The test passes. Using the same component in a Blazor WASM app results in one render each time the parameter changes, but in BUnit I get three (edit: four). This is not just a problem with the "RenderCount" property, the actual render method is being called four times as well (confirmed with a breakpoint).

Version info:

  • bUnit version: 1.20.8
  • .NET Runtime and Blazor version: .NET 6.0
  • OS type and version: Windows 10

Additional context:

I am obviously not calling StateHasChanged() multiple times in succession like the example above, but there are lots of dependencies etc. which can result in redundant calls to StateHasChanged. In a normal Blazor app, the calls would get "batched" into a single render, so long as they occur synchronously.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workinghelp wantedExtra attention is neededinput neededWhen an issue requires input or suggestionsinvestigateThis issue require further investigation before closing.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions