In this project, we are testing our previous Blazor Web App. We have extended it with a Counter component in order to test the click of a button on the UI with bUnit.
In summary, we are testing:
Home.razorpage listsProductscorrectly.ProductCard.razorcomponent renders correctly.Counter.razorcomponent behaves as expected when the increment button is clicked.
bUnit is a testing library for Blazor components. It allows us to render components in a test context and verify their behavior and rendered markup.
It integrates naturally with xUnit.
We add the NuGet package to our test project with dotnet add package bunit
Assuming we have the following component (HelloComponent.razor):
<h3>Hello @Name</h3>
@code {
[Parameter]
public string Name { get; set; } = string.Empty;
}using Bunit;
using Xunit;
public class HelloComponentTests : BunitContext
{
[Fact]
public void Component_ShouldRenderNameCorrectly()
{
// Arrange
var name = "Yosmel";
// Act
var cut = Render<HelloComponent>(
parameters => parameters.Add(p => p.Name, name)
);
// Assert
cut.MarkupMatches("<h3>Hello Yosmel</h3>");
}
}BunitContext provides the test environment for rendering components.
Our testing class can inherit from it:
public class MyComponentTests : BunitContextInstead of inheriting from BunitContext, we can instantiate it directly:
using var ctx = new BunitContext();
var cut = ctx.Render<HelloComponent>();This is useful when:
- We prefer composition over inheritance
- We want isolated contexts per test
Renders a Blazor component inside the test environment.
var cut = Render<MyComponent>();We can query the rendered HTML:
cut.Find("h3");
cut.Find("button");
cut.Find("#my-id");We can simulate user interactions:
cut.Find("button").Click();
cut.Find("input").Change("new value");Assertions:
- MarkupMatches()
- Find()
- FindAll()
cut.MarkupMatches("<p>Expected content</p>");[Fact]
public void Counter_ShouldIncrement_WhenButtonClicked()
{
// Arrange
var cut = Render<Counter>();
// Act
cut.Find("button").Click();
// Assert
cut.MarkupMatches("""
<p>Current count: 1</p>
<button>Click me</button>
""");
}cutstands for Component Under Test (bUnit convention).Find()andFindAll()asserton methods come from bUnit.Assert.*methods come from xUnit.Render<T>()renders the component and applies parameters via a builder used with lambda syntax.
- Clone the project with
git clone. - Run tests with
dotnet test