Repository navigation
when SetParametersAsync is used (only async) - BuildRenderTree is not invoked #1695
Copy link
Copy link
Closed
Description
Several issues are related to SetParametersAsync, but I am unsure whether they are the same as mine, so I tried creating a new incident.
Describe the bug
When a component has SetParametersAsync then BuildRenderTree is not invoked.
Example:
Testing this component:
using Microsoft.AspNetCore.Components;
using Microsoft.AspNetCore.Components.Rendering;
namespace ClassLibrary1;
public class ComponentWithAsyncSetParameters : ComponentBase
{
public override async Task SetParametersAsync(ParameterView parameters)
{
await Task.Delay(1000);
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(1, "h1");
builder.AddContent(2, "HEADER TEXT");
builder.CloseElement();
}
}
public class ComponentWithoutAsyncSetParameters : ComponentBase
{
public override Task SetParametersAsync(ParameterView parameters)
{
return Task.CompletedTask;
}
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(1, "h1");
builder.AddContent(2, "HEADER TEXT");
builder.CloseElement();
}
}
public class ComponentWithoutSetParameters : ComponentBase
{
protected override void BuildRenderTree(RenderTreeBuilder builder)
{
builder.OpenElement(1, "h1");
builder.AddContent(2, "HEADER TEXT");
builder.CloseElement();
}
}With this test:
using Bunit;
using ClassLibrary1;
namespace TestProject1;
public sealed class UnitTest1 : TestContext
{
[Fact]
public void TestComponentWithAsyncSetParameters()
{
const string expected = "<h1>HEADER TEXT</h1>";
var component = RenderComponent<ComponentWithAsyncSetParameters>();
component.MarkupMatches(expected);
}
[Fact]
public void TestComponentWithoutAsyncSetParameters()
{
const string expected = "<h1>HEADER TEXT</h1>";
var component = RenderComponent<ComponentWithoutAsyncSetParameters>();
component.MarkupMatches(expected);
}
[Fact]
public void TestComponentWithoutSetParameters()
{
const string expected = "<h1>HEADER TEXT</h1>";
var component = RenderComponent<ComponentWithoutSetParameters>();
component.MarkupMatches(expected);
}
}Bunit.HtmlEqualException: HTML comparison failed.
Bunit.HtmlEqualException
HTML comparison failed.
The following errors were found:
1: The element at h1(0) is missing.
Actual HTML:
Expected HTML:
<h1>HEADER TEXT</h1>
at Bunit.MarkupMatchesAssertExtensions.MarkupMatches(INodeList actual, INodeList expected, String userMessage) in /_/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs:line 238
at Bunit.MarkupMatchesAssertExtensions.MarkupMatches(IRenderedFragment actual, String expected, String userMessage) in /_/src/bunit.web/Asserting/MarkupMatchesAssertExtensions.cs:line 114
at TestProject1.UnitTest1.TestComponentWithoutAsyncSetParameters() in C:\Users\Mihails Kuzmins\source\repos\ClassLibrary1\TestProject1\UnitTest1.cs:line 23
at InvokeStub_UnitTest1.TestComponentWithoutAsyncSetParameters(Object, Object, IntPtr*)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
Expected behavior:
BuildRenderTree is invoked, and the valid HTML is rendered
Version info:
- bUnit version: 1.38.5
- .NET Runtime and Blazor version: net9.0; 9.0.3
- OS type and version: Windows 10.0.26100.3624
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels


Activity
linkdotnet commentedon Mar 31, 2025
Hey @mku-vesca,
maybe we can talk through examples of why certain things are happening. The easiest is
ComponentWithAsyncSetParameters: You have aTask.Delay. Or a "real" async task that isn't directly finished.The
RenderComponentdoesn't await until all lifecycles areawaitedas well. Blazor sees that you have aTaskobject and renders already something even if yourSetParametersAsyncmethod isn't completely done. bUnit behaves the same.While your render-tree might not need any parameter, Blazor anyways enters your
SetParametersAsyncmethod and batches the continuation (maybe it is that it doesn't have to wait 1 second). as bUnit is not blocking, you directly in yourMarkupMatchesmethod.The normal way to do it would be taking:
WaitFor- Helpers: https://bunit.dev/docs/interaction/awaiting-async-state.htmlBut even if you would do that, let's come to your second example:
In your second example, you are overriding
SetParametersAsync: https://source.dot.net/#Microsoft.AspNetCore.Components/ComponentBase.cs,259The default implementation has a bit logic, therefore
base.SetParametersAsyncis advised.If you are not calling
base, no one is invoking a render cycle when the component is created the first time (there is aStateHasChangedcall inside that chain).I would assume, that such a component will not be rendered in Blazor as well. Because bUnit doesn't do anything special here.
So it boils down to: When overriding
SetParametersAsyncyou have to manually instruct Blazor to render. In the last example, where you did not override, that is done automatically.linkdotnet commentedon Mar 31, 2025
That seems to be an internal issue of Blazor itself, which leads to an error.
I expect that spinning up a "normal" Blazor WebApp will lead to the same exception.
If it is fine with you, I will convert this into a discussion.