Introduction to bUnit: Unit Testing Blazor Applications

Per definition, bUnit is a testing library for Blazor Components. Its goal is to make it easy to write comprehensive, stable unit tests.

bUnit is a testing library for Blazor Components that allows developers to write comprehensive and stable unit tests. It enables setting up and defining components, verifying outcomes, interacting with and inspecting components, passing parameters and services, and mocking various features. bUnit uses existing testing frameworks and runs tests quickly.

Setting up Your Environment

Before you can start using bUnit, you need to set up our development environment. First, you need to create a new Blazor project. Open up Visual Studio, and create a new Blazor project.

After you create your project, which has some default components and C# classes, you need to create a Testing project. You can use any Testing project template that you like, ex: xUnit, MSUnit, etc as bUnit is compatible with all of them.

In the test project, install the bUnit Nuget package. To do this, you can either use the CMD command Install-Package bUnit or you can right-click on your project in the Solution Explorer, and select “Manage NuGet Packages”. In the NuGet Package Manager, search for “bUnit”, and click the “Install” button to install the package.

With bUnit you can create simple testing scenarios, or some more advanced ones like unit testing Authentication, HttpClient requests, and much more. Below, you will learn about 2 commonly used unit testing cases.

Unit Testing Markup

Unit testing markup is one of the simplest ways of unit testing your Blazor components and as the name already indicates it is used to check if the component UI is rendered as expected.

I have created a simple Blazor component named Welcome which has only some HTML code

@page "/"

<PageTitle>Welcome</PageTitle>

<h1>www.dotnethow.net</h1>
<div>Learn all you need to know about .NET</div>

Here’s an example markup unit test for the component:

using Bunit;
using Xunit;

public class IndexPageTests
{
    [Fact]
    public void PageMarkup_IsCorrect()
    {
        // Arrange
        using var ctx = new TestContext();
        var cut = ctx.RenderComponent<Welcome>();

        // Act

        // Assert
        cut.MarkupMatches(@"<PageTitle>Welcome</PageTitle>
                            <h1>www.dotnethow.net</h1>
                            <div>Learn all you need to know about .NET</div>");
    }
}

This test uses the MarkupMatches() method from the TestMarkup class to verify that the rendered markup of the Welcome component matches the expected markup. The expected markup includes a PageTitle component with the text “Welcome”, an h1 element with the text “www.dotnethow.net“, and a div element with the text “Learn all you need to know about .NET”.

Now, to the same Blazor component let us add a button with a click event.

Unit Testing Events

The updated component would look like below

@page "/"

<PageTitle>Welcome</PageTitle>

<h1>www.dotnethow.net</h1>
<div>Learn all you need to know about .NET</div>

<button @onclick="IncrementSubscriberCount">Subscribe for more</button>
<p>
    Current subscribers: @number
</p>

@code {
    int number = 17200;

    void IncrementSubscriberCount()
    {
        number++;
    }
}

This implementation adds a button with the “Subscribe for more” text to the component’s markup. The @onclick attribute is used to bind the IncrementSubscriberCount method to the button’s click event.

The @code block includes a number field that tracks the current value of the number to be incremented, and the IncrementSubscriberCount method that increments the number field by one each time it is called.

Now, let us write a unit test to check if the “Subscribe for more” button works as expected. An example unit test would look like below:

[Fact]
public void SubscriberCountShouldIncrementWhenClicked()
{
  // Arrange: render the Welcome.razor component
  using var ctx = new TestContext();
  var cut = ctx.RenderComponent<Welcome>();

  // Assert: first find the <p> element, then verify its content
  cut.Find("p").MarkupMatches("<p>Current count: 17200</p>");

  // Act: find and click the <button> element to increment
  // the counter in the <p> element
  cut.Find("button").Click();

  // Assert: first find the <p> element, then verify its content
  cut.Find("p").MarkupMatches("<p>Current count: 17201</p>");
}

The unit test above uses the bUnit library to render the component and simulate a button click. It verifies that the initial value of the number variable is 17200, clicks the button to increment the value, and then checks that the updated value is 17201.

What else?

With bUnit you can create way more advanced scenarios, like unit testing IJSRuntime, faking Authorization, unit testing Navigation manager, and much more. To learn more about bUnit you can check out their official documentation or my Pluralsight course, Unit Testing Blazor Applications.


Enjoyed this post? Subscribe to my YouTube channel for more great content. Your support is much appreciated. Thank you!


Check out my Udemy profile for more great content and exclusive learning resources! Thank you for your support.
Ervis Trupja - Udemy



Enjoyed this blog post? Share it with your friends and help spread the word! Don't keep all this knowledge to yourself.