### Install bUnit template
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Install the bUnit project template from NuGet. This command only needs to be run once.
```bash
dotnet new install bunit.template
```
--------------------------------
### bUnit Test Project .csproj with MSTest
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Example .csproj file configuration for a bUnit test project using MSTest. This setup includes bUnit, the .NET test SDK, MSTest packages, and a project reference.
```xml
net8.0enablefalse
```
--------------------------------
### HelloWorld Component Example
Source: https://bunit.dev/docs/test-doubles/fake-webassemblyhostenvironment.html
This component injects IWebAssemblyHostEnvironment and displays a greeting based on the environment and the base address.
```razor
@inject IWebAssemblyHostEnvironment HostEnvironment
```
--------------------------------
### Base Markup for Customization Examples
Source: https://bunit.dev/docs/verification/semantic-html-comparison.html
This is the base HTML structure used for demonstrating various customization options. It serves as a reference for the subsequent examples.
```html
Hello world
```
--------------------------------
### Component Markup Example
Source: https://bunit.dev/docs/verification/verify-markup.html
The HTML structure of the example Heading component.
```html
Heading text
Secondary text
```
--------------------------------
### Using MockHttpClient in Tests
Source: https://bunit.dev/docs/test-doubles/mocking-httpclient.html
Register the mock HttpClient and configure a response for a specific endpoint. This example shows how to set up a mock response for a GET request to '/getData'.
```csharp
var mock = Services.AddMockHttpClient();
mock.When("/getData").RespondJson(new List{ ... });
```
--------------------------------
### Setup JSInterop for JavaScript Module Calls
Source: https://bunit.dev/docs/test-doubles/emulating-ijsruntime.html
Configure bUnit's JSInterop to handle calls to a specific JavaScript module and function. Use `SetupModule` to identify the module and `SetupVoid` or `Setup` for the function.
```csharp
var moduleInterop = JSInterop.SetupModule("hello.js");
moduleInterop.SetupVoid("world");
```
--------------------------------
### bUnit Test Project .csproj with xUnit v3
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Example .csproj file configuration for a bUnit test project using xUnit v3. Note the specific xunit.v3 package reference.
```xml
net8.0enablefalseExeruntime; build; native; contentfiles; analyzers; buildtransitiveall
```
--------------------------------
### bUnit Test Project .csproj with NUnit
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Example .csproj file configuration for a bUnit test project using NUnit. Includes bUnit, the .NET test SDK, NUnit packages, and a project reference.
```xml
net8.0enablefalse
```
--------------------------------
### bUnit Test Project .csproj with TUnit
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Example .csproj file configuration for a bUnit test project using TUnit. Note the use of `Microsoft.NET.Sdk` instead of `Microsoft.NET.Sdk.Razor` due to TUnit's limitations with source generators.
```xml
net8.0enablefalsefalse
```
--------------------------------
### bUnit Test Project .csproj with xUnit
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Example .csproj file configuration for a bUnit test project using xUnit as the test framework. Ensure bUnit and test runner packages are included.
```xml
net8.0enablefalseruntime; build; native; contentfiles; analyzers; buildtransitiveall
```
--------------------------------
### WeatherForecast Component Example
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
This component demonstrates fetching data from a service and requires `IWeatherForecastService` to be injected.
```razor
@inject IWeatherForecastService ForecastService
Weather forecast
This component demonstrates fetching data from a service.
@if (Forecasts is null)
{
Loading...
}
else
{
}
@code
{
public WeatherForecast[] Forecasts { get; private set; }
protected override async Task OnInitializedAsync()
{
Forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
}
}
```
--------------------------------
### Semantic HTML Comparison Example
Source: https://bunit.dev/docs/verification/verify-markup.html
Demonstrates how two HTML fragments with insignificant whitespace differences are considered equal by the semantic comparer.
```html
Foo Bar
```
```html
Foo Bar
```
--------------------------------
### Add Localization Services
Source: https://bunit.dev/docs/test-doubles/mocking-localizer.html
Add bUnit's localization services to your test context. This is a required setup step before you can mock the localizer.
```csharp
BunitContext.Services.AddLocalization();
```
--------------------------------
### Handle image file upload and preview
Source: https://bunit.dev/docs/test-doubles/input-file.html
This example demonstrates how to handle image file uploads within a Blazor component, including requesting a resized image preview and converting it to a base64 string for display. Note that bUnit has limitations with `RequestImageFileAsync` in tests.
```csharp
@code {
private string imageBase64 = string.Empty;
private async Task Upload(InputFileChangeEventArgs args)
{
var file = args.File;
var preview = await file.RequestImageFileAsync("image/png", 100, 100);
await using var stream = preview.OpenReadStream();
var buffer = new byte[stream.Length];
await using var memoryStream = new MemoryStream(buffer);
await stream.CopyToAsync(memoryStream);
var base64 = Convert.ToBase64String(buffer);
imageBase64 = $"data:image/png;base64,{base64}";
}
}
```
--------------------------------
### Setup JS Interop with Immediate Result
Source: https://bunit.dev/docs/test-doubles/emulating-ijsruntime.html
Configure a specific JavaScript interop call to return a predefined result. Use this when the component expects a specific return value from a JavaScript function.
```csharp
JSInterop.Setup("getPageTitle").SetResult("bUnit is awesome");
```
--------------------------------
### AsyncData component example
Source: https://bunit.dev/docs/interaction/awaiting-async-state.html
This component awaits data from a TextService in OnInitializedAsync and re-renders when data is available.
```csharp
@text
@code
{
string text = string.Empty;
[Parameter] public Task TextService { get; set; }
protected override async Task OnInitializedAsync()
{
text = await TextService;
}
}
```
--------------------------------
### Instantiate BunitContext with xUnit
Source: https://bunit.dev/docs/getting-started/writing-tests.html
Demonstrates how to instantiate BunitContext explicitly within an xUnit test method. This is useful when you need more control over the test setup or are not inheriting from BunitContext.
```csharp
public class HelloWorldExplicitContext
{
[Fact]
public void HelloWorldComponentRendersCorrectly()
{
// Arrange
using var ctx = new BunitContext();
// Act
var cut = ctx.Render();
// Assert
cut.MarkupMatches("
Hello world from Blazor
");
}
}
```
--------------------------------
### UserInfo Component Example
Source: https://bunit.dev/docs/test-doubles/auth.html
This component displays user information and authorization status based on the current authentication state. It relies on `AuthenticationStateProvider`, ``, and ``.
```razor
@using Microsoft.AspNetCore.Components.Authorization
@inject AuthenticationStateProvider AuthenticationStateProvider
@if (isAuthenticated)
{
Welcome @userName
}
@if (!isAuthenticated)
{
Please log in!
}
State: Authorized
State: Authorizing
State: Not authorized
@code
{
bool isAuthenticated = false;
string userName;
protected override async Task OnParametersSetAsync()
{
var state = await AuthenticationStateProvider.GetAuthenticationStateAsync();
isAuthenticated = state.User.Identity.IsAuthenticated;
userName = state.User.Identity.Name;
}
}
```
--------------------------------
### Using Custom Service Provider Factory with bUnit
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Register a custom service provider factory with bUnit to manage dependency injection. This example demonstrates using the previously defined CustomServiceProviderFactory.
```csharp
using Bunit;
using Xunit;
public class CustomFactoryTests : TestContext
{
[Fact]
public void UseCustomServiceProviderFactory()
{
Services.UseServiceProviderFactory(new CustomServiceProviderFactory());
var dummyService = Services.GetService();
Assert.NotNull(dummyService);
}
}
```
--------------------------------
### UserRights Component Example
Source: https://bunit.dev/docs/test-doubles/auth.html
This component demonstrates how to use AuthorizeView to conditionally render content based on user roles, claims, and policies.
```razor
@using Microsoft.AspNetCore.Components.Authorization
@using System.Security.Claims
@using System.Globalization
Hi @context.User.Identity.Name, you have these claims and rights:
@code
{
private static string GetClaimName(Claim claim)
{
var claimType = new Uri(claim.Type);
var name = claimType.Segments.Last();
return CultureInfo.InvariantCulture.TextInfo.ToTitleCase(name);
}
}
```
--------------------------------
### Setup Void JS Interop and Complete Later
Source: https://bunit.dev/docs/test-doubles/emulating-ijsruntime.html
Set up a JavaScript interop call that does not return a value. The `SetVoidResult()` method is used to signal that the operation has completed, allowing the component to proceed.
```csharp
var plannedInvocation = JSInterop.SetupVoid("startAnimation");
// ... other test code
// Later in the test, mark the invocation as completed.
// SetResult() is not used in this case since InvokeVoidAsync
// only completes or throws, it doesn’t return a value.
// Any calls to InvokeVoidAsync(...) up till this point will
// have received an incomplete Task which the component
// is awaiting until the call to SetVoidResult() below.
plannedInvocation.SetVoidResult();
```
--------------------------------
### Instantiate BunitContext with MSTest
Source: https://bunit.dev/docs/getting-started/writing-tests.html
Illustrates explicit BunitContext instantiation for MSTest. This approach is beneficial when you need to manage test context independently or integrate with custom testing setups.
```csharp
[TestClass]
public class HelloWorldExplicitContext
{
[TestMethod]
public void HelloWorldComponentRendersCorrectly()
{
// Arrange
using var ctx = new Bunit.BunitContext();
// Act
var cut = ctx.Render();
// Assert
cut.MarkupMatches("
Hello world from Blazor
");
}
}
```
--------------------------------
### Generate Component Stub with AddStub
Source: https://bunit.dev/docs/extensions/bunit-generators.html
Automatically generates a stub for a component using `ComponentFactories.AddStub()`. This is useful for third-party components that require extensive setup.
```csharp
[Fact]
public void Text_button_gets_initial_count()
{
// This call will automatically generate a stub for the ThirdPartyButton component
// with the name "ThirdPartyButtonStub"
ComponentFactories.AddStub();
var cut = Render(@);
cut.Find("button").Click();
// Retrieves the stub from the render tree and checks if the text is "1"
cut.FindComponent().Instance.Text.Should().Be("1");
}
```
--------------------------------
### Using AutofacServiceProviderFactory with bUnit
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Register an Autofac service provider factory to use Autofac for dependency injection in bUnit tests. Ensure the Autofac.Extensions.DependencyInjection package is installed.
```csharp
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Bunit;
using Xunit;
public class AutofacTests : TestContext
{
[Fact]
public void AutofacServiceProviderViaFactoryReturns()
{
void ConfigureContainer(ContainerBuilder containerBuilder)
{
containerBuilder
.RegisterType()
.AsSelf();
}
Services.UseServiceProviderFactory(new AutofacServiceProviderFactory(ConfigureContainer));
//get a service which was installed in the Autofac ContainerBuilder
var dummyService = Services.GetService();
Assert.NotNull(dummyService);
//get a service which was installed in the bUnit ServiceCollection
var BunitContext = Services.GetService();
Assert.NotNull(BunitContext);
Assert.Equal(this, BunitContext);
}
}
```
--------------------------------
### Semantic HTML Comparison with MarkupMatches
Source: https://bunit.dev/docs/verification/semantic-html-comparison.html
Demonstrates using the `MarkupMatches()` method with semantic comparison attributes to verify rendered component markup. This example uses RegEx for an `id` attribute and ignores a specific child element.
```csharp
var cut = Render();
// Assert
// Here we specify expected HTML from CUT.
var expectedHtml = @"
Heading text
";
// Here we use the HTML diffing library to assert that the rendered HTML
// from CUT is semantically the same as the expected HTML string above.
cut.MarkupMatches(expectedHtml);
}
```
--------------------------------
### Using AutofacServiceProvider via delegate with bUnit
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Configure Autofac services using a delegate that builds and returns an Autofac lifetime scope. This method allows for more control over the Autofac container setup.
```csharp
using Autofac;
using Autofac.Extensions.DependencyInjection;
using Bunit;
using Microsoft.Extensions.DependencyInjection;
using Xunit;
public class AutofacDelegateTests : TestContext
{
[Fact]
public void AutofacServiceProviderViaDelegateReturns()
{
ILifetimeScope ConfigureContainer(IServiceCollection services)
{
var containerBuilder = new ContainerBuilder();
containerBuilder
.RegisterType()
.AsSelf();
containerBuilder.Populate(services);
return containerBuilder.Build();
}
Services.UseServiceProviderFactory(x => new AutofacServiceProvider(ConfigureContainer(x)));
//get a service which was installed in the Autofac ContainerBuilder
var dummyService = Services.GetService();
Assert.NotNull(dummyService);
//get a service which was installed in the bUnit ServiceCollection
var BunitContext = Services.GetService();
Assert.NotNull(BunitContext);
Assert.Equal(this, BunitContext);
}
}
```
--------------------------------
### Setup JSInterop for IJSObjectReference Calls
Source: https://bunit.dev/docs/test-doubles/emulating-ijsruntime.html
Configure bUnit's JSInterop to handle calls to a JavaScript function on an `IJSObjectReference` identified by a specific matcher. This is useful when the `IJSObjectReference` is obtained via `InvokeAsync`.
```csharp
var objectReference = JSInterop.SetupModule(matcher => matcher.Identifier == "SomeModule.GetInstance");
objectReference.SetupVoid("world");
```
--------------------------------
### Use BunitContext Per Test Method (Razor)
Source: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html
This Razor example demonstrates creating a `BunitContext` instance within a test method using a `using` statement. This is an alternative to class-level inheritance for managing the test context.
```razor
@code
{
[Fact]
public void HelloWorldComponentRendersCorrectly()
{
// Arrange
using var ctx = new BunitContext();
// Act
var cut = ctx.Render(@);
// Assert
cut.MarkupMatches(@
Hello world from Blazor
);
}
}
```
--------------------------------
### Configure and Navigate to Login
Source: https://bunit.dev/docs/test-doubles/navigation-manager.html
Demonstrates how to set up InteractiveRequestOptions for dynamic login, including specifying interaction type and return URL, and adding additional parameters.
```csharp
InteractiveRequestOptions requestOptions = new()
{
Interaction = InteractionType.SignIn,
ReturnUrl = NavigationManager.Uri,
};
requestOptions.TryAddAdditionalParameter("prompt", "login");
NavigationManager.NavigateToLogin("authentication/login", requestOptions);
```
--------------------------------
### Create bUnit test project with xUnit
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new bUnit test project using the bUnit template, specifying xUnit as the testing framework. Replace with your desired project name.
```bash
dotnet new bunit --framework xunit -o
```
--------------------------------
### Recommended bUnit Project Structure
Source: https://bunit.dev/docs/misc-test-tips.html
Illustrates a recommended solution and project structure for setting up test and production code projects.
```plaintext
src
| MyComponentLib.csproj (namespace e.g. "Company.MyComponentLib")
| _Imports.razor
| Component1.razor
| SubFolder
| SubComponent1.razor
test
| MyComponentLibTests.csproj (with project reference to MyComponentLib.csproj)
| _Imports.razor
| Component1Test.cs
| SubFolder
| SubComponent1Test.cs
```
--------------------------------
### Component definition for InvokeAsync example
Source: https://bunit.dev/docs/interaction/trigger-renders.html
This is a simple Blazor component with a Calculate method that updates a result and calls StateHasChanged().
```razor
@code
{
int result = 0;
public void Calculate(int x, int y)
{
result = x + y;
StateHasChanged();
}
}
```
--------------------------------
### Custom Service Provider Factory Implementation
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Provides dummy implementations for IServiceProvider, IServiceScopeFactory, and IServiceProviderFactory. These are for demonstration and not intended for production use.
```csharp
using Microsoft.Extensions.DependencyInjection;
public sealed class CustomServiceProvider : IServiceProvider, IServiceScopeFactory, IServiceScope
{
private readonly IServiceProvider _serviceProvider;
public CustomServiceProvider(IServiceCollection serviceDescriptors)
=> _serviceProvider = serviceDescriptors.BuildServiceProvider();
public object GetService(Type serviceType)
{
if (serviceType == typeof(IServiceScope) || serviceType == typeof(IServiceScopeFactory))
return this;
if (serviceType == typeof(DummyService))
return new DummyService();
return _serviceProvider.GetService(serviceType);
}
void IDisposable.Dispose() { }
public IServiceScope CreateScope() => this;
IServiceProvider IServiceScope.ServiceProvider => this;
}
public sealed class CustomServiceProviderFactoryContainerBuilder
{
private readonly IServiceCollection _serviceDescriptors;
public CustomServiceProviderFactoryContainerBuilder(IServiceCollection serviceDescriptors)
=> this._serviceDescriptors = serviceDescriptors;
public IServiceProvider Build()
=> new CustomServiceProvider(_serviceDescriptors);
}
public sealed class CustomServiceProviderFactory : IServiceProviderFactory
{
public CustomServiceProviderFactoryContainerBuilder CreateBuilder(IServiceCollection services)
=> new CustomServiceProviderFactoryContainerBuilder(services);
public IServiceProvider CreateServiceProvider(CustomServiceProviderFactoryContainerBuilder containerBuilder)
=> containerBuilder.Build();
}
```
--------------------------------
### Get IStringLocalizer Instance
Source: https://bunit.dev/docs/test-doubles/mocking-localizer.html
Retrieve an instance of IStringLocalizer from the bUnit test context. This instance can then be used to verify localized string outputs.
```csharp
var localizer = ctx.Services.GetService>();
```
--------------------------------
### Create bUnit test project with NUnit
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new bUnit test project using the bUnit template, specifying NUnit as the testing framework. Replace with your desired project name.
```bash
dotnet new bunit --framework nunit -o
```
--------------------------------
### Initialize bUnit Context with xUnit Logger
Source: https://bunit.dev/docs/misc-test-tips.html
Demonstrates how to initialize a bUnit test class to capture log messages by passing ITestOutputHelper to the AddXunitLogger extension method in the constructor.
```csharp
using System;
using Microsoft.Extensions.DependencyInjection;
using Bunit;
using Xunit;
using Xunit.Abstractions;
namespace MyTests;
public class MyComponenTest : BunitContext
{
public MyComponenTest(ITestOutputHelper outputHelper)
{
Services.AddXunitLogger(outputHelper);
}
[Fact]
public void Test() ...
```
--------------------------------
### Create bUnit test project with xUnit v3
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new bUnit test project using the bUnit template, specifying xUnit v3 as the testing framework. Replace with your desired project name.
```bash
dotnet new bunit --framework xunitv3 -o
```
--------------------------------
### Create new xUnit v3 test project manually
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new xUnit v3 test project manually. Replace with your desired project name.
```bash
dotnet new xunit3 -o
```
--------------------------------
### Add MockHttpClient Package Reference
Source: https://bunit.dev/docs/test-doubles/mocking-httpclient.html
Add this package reference to your test project's .csproj file to use RichardSzalay.MockHttp.
```xml
```
--------------------------------
### Get Raw Component Markup
Source: https://bunit.dev/docs/verification/verify-markup.html
Access the raw rendered HTML markup of a component as a string using the Markup property. Standard string assertions can then be performed on this markup.
```csharp
var renderedMarkup = cut.Markup;
Assert.Equal("
Hello world from Blazor
", renderedMarkup);
```
--------------------------------
### Add test project to solution and reference component project
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Add the newly created test project to your solution file and establish a project reference from the test project to the project containing the components to be tested. This allows the test project to access and test the components.
```bash
dotnet sln .sln add
dotnet add .csproj reference .csproj
```
--------------------------------
### NUnit Test with FixtureLifeCycle Attribute
Source: https://bunit.dev/docs/getting-started/writing-tests.html
An NUnit test demonstrating the use of FixtureLifeCycle.InstancePerTestCase attribute for creating a new test class instance per test. This simplifies test setup.
```csharp
[FixtureLifeCycle(LifeCycle.InstancePerTestCase)]
public class HelloWorldInstancePerTestCase : Bunit.BunitContext
{
[Test]
public void HelloWorldComponentRendersCorrectly()
{
// Act
var cut = Render();
// Assert
cut.MarkupMatches("
Hello world from Blazor
");
}
}
```
--------------------------------
### Accessing Component Instance
Source: https://bunit.dev/docs/verification/verify-component-state.html
Use the Instance property on IRenderedComponent to get direct access to the component under test. Note that modifying parameters directly through Instance does not trigger a re-render.
```csharp
RenderedComponent cut = Render();
Alert alert = cut.Instance;
// Assert against instance
```
--------------------------------
### Simulate binary file upload to InputFile component
Source: https://bunit.dev/docs/test-doubles/input-file.html
This test demonstrates uploading binary content to an `InputFile` component. It highlights a known limitation where `UploadFiles` may fail when used with `RequestImageFileAsync` due to Blazor's internal checks, causing assertions on the image source or unhandled exceptions to fail.
```csharp
[Fact]
public void UploadFileTest()
{
var cut = Render();
cut.FindComponent().UploadFiles(InputFileContent.CreateFromBinary([1,2], "test.png"));
cut.Find("img").GetAttribute("src").Should().NotBeNullOrEmpty(); // Will fail
Renderer.UnhandledException.Should().BeNull(); // Will fail
}
```
--------------------------------
### Create new xUnit test project manually
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new xUnit test project manually. Replace with your desired project name.
```bash
dotnet new xunit -o
```
--------------------------------
### Create bUnit test project with MSTest
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new bUnit test project using the bUnit template, specifying MSTest as the testing framework. Replace with your desired project name.
```bash
dotnet new bunit --framework mstest -o
```
--------------------------------
### Testing Component with Query String Parameters
Source: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html
Tests a component that receives parameters from the query string by configuring the NavigationManager and then rendering the component. Asserts that the component instance correctly receives the parameter.
```csharp
@inherits BunitContext
@code {
[Fact]
public void Component_receives_parameters_from_query_string()
{
var navigationManager = Services.GetRequiredService();
var uri = navigationManager.GetUriWithQueryParameter("Name", "bUnit");
navigationManager.NavigateTo(uri);
var cut = Render();
cut.Instance.Name.ShouldBe("bUnit");
}
}
```
--------------------------------
### Create new TUnit test project manually
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new TUnit test project manually. Replace with your desired project name.
```bash
dotnet new TUnit -o
```
--------------------------------
### Setting Environment to Development
Source: https://bunit.dev/docs/test-doubles/fake-webassemblyhostenvironment.html
Use this snippet to set the environment to 'Development' for testing. Helper methods like SetEnvironmentToProduction() and SetEnvironmentToStaging() are also available, or you can directly modify the Environment property.
```csharp
// Arrange
var hostEnvironment = Services.GetRequiredService();
// Sets the environment to "Development". There are two other helper
// methods available as well, SetEnvironmentToProduction() and
// set SetEnvironmentToStaging(), or environment can also be changed
// directly through the hostEnvironment.Environment property.
hostEnvironment.SetEnvironmentToDevelopment();
var cut = Render();
// Assert - inspects markup to verify the message
cut.Find("#message").MarkupMatches("
Hello Developers.
");
```
--------------------------------
### Conditionally Add CascadingValue to Root Render Tree
Source: https://bunit.dev/docs/providing-input/root-render-tree.html
Use `TryAdd` to add a `CascadingValue` component to the root render tree only if a component of the same type has not already been added. This prevents duplicate additions in shared setup logic.
```csharp
RenderTree.TryAdd>(parameters => parameters
.Add(p => p.Value, "BAR?")
);
```
--------------------------------
### Test NavigationManager.NavigateToLogin
Source: https://bunit.dev/docs/test-doubles/navigation-manager.html
Shows how to test the NavigationManager.NavigateToLogin function by retrieving navigation history and asserting the properties of InteractiveRequestOptions.
```csharp
var navigationManager = Services.GetRequiredService();
ActionToTriggerTheNavigationManager();
// This helper method retrieves the InteractiveRequestOptions object
var requestOptions = navigationManager.History.Last().StateFromJson();
Asser.NotNull(requestOptions);
Assert.Equal(requestOptions.Interaction, InteractionType.SignIn);
options.TryGetAdditionalParameter("prompt", out string prompt);
Assert.Equal(prompt, "login");
```
--------------------------------
### Set Roles, Claims, and Policies for User
Source: https://bunit.dev/docs/test-doubles/auth.html
Use this snippet to configure a user with multiple roles, claims, and policies. This is useful for testing authorization logic that depends on a combination of these attributes.
```csharp
// Arrange
var authContext = AddAuthorization();
authContext.SetAuthorized("TEST USER");
authContext.SetRoles("admin", "superuser");
authContext.SetPolicies("content-editor");
authContext.SetClaims(new Claim(ClaimTypes.Email, "test@example.com"));
// Act
var cut = Render();
// Assert
cut.MarkupMatches(@"
Hi TEST USER, you have these claims and rights:
Emailaddress: test@example.com
You have the role SUPER USER
You have the role ADMIN
You are a CONTENT EDITOR
");
```
--------------------------------
### Test FetchData: Verify Persisted State Loading
Source: https://bunit.dev/docs/test-doubles/persistentcomponentstate.html
Arrange the test by adding `BunitPersistentComponentState` and persisting mock data. Then, render the `FetchData` component and assert that the persisted data is rendered, preventing the component from fetching new data.
```csharp
// Arrange
var state = AddBunitPersistentComponentState();
// Persist a single weather forecast with a temperature of 42
state.Persist("weather-data", new [] { new WeatherForecast { Temperature = 42 } });
// Act
var cut = Render();
// Assert - verify that the persisted forecast was rendered out
cut.MarkupMatches("
42
");
```
--------------------------------
### Add bUnit package to test project
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Add the bUnit package to an existing test project. Navigate to the test project directory first, then run this command. Ensure you use the desired version of bUnit.
```bash
cd
dotnet add package bunit --version 2.7.2
```
--------------------------------
### Upload text file to InputFile component
Source: https://bunit.dev/docs/test-doubles/input-file.html
Use `InputFileContent.CreateFromText` to create file content and `UploadFile` to simulate the upload. This is useful for testing components that handle text-based file uploads.
```csharp
InputFileContent fileToUpload = InputFileContent.CreateFromText("Text content", "Filename.txt");
RenderedComponent cut = Render();
RenderedComponent inputFile = cut.FindComponent();
inputFile.UploadFile(fileToUpload);
// Assertions...
```
--------------------------------
### Configure .NET 8.0 Target Framework
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Modify the .csproj file to target .NET 8.0 or later for your bUnit test project.
```xml
net8.0 ...
```
--------------------------------
### Mock Component with NSubstitute
Source: https://bunit.dev/docs/providing-input/substituting-components.html
Substitute a component with a mock object created using the NSubstitute library. This is an alternative to Moq for creating mock instances.
```csharp
[Fact]
public void Foo_Doesnt_Have_A_Bar_But_Mock()
{
// Register the mock instance for Bar
Bar barMock = Substitute.For();
ComponentFactories.Add(barMock);
// Render the component under test
RenderedFragment cut = Render(@);
// Verify that the Bar component has
// been substituted in the render tree
RenderedComponent bar = cut.FindComponent();
Assert.Same(barMock, bar.Instance);
}
```
--------------------------------
### Test FetchData: Verify State Persistence
Source: https://bunit.dev/docs/test-doubles/persistentcomponentstate.html
Render the `FetchData` component, then trigger its `OnPersisting` callback using `state.TriggerOnPersisting()`. Assert that state was successfully saved by checking if `TryTake` returns true and the saved state is not empty.
```csharp
// Arrange
var state = AddBunitPersistentComponentState();
var cut = Render();
// Act - trigger the FetchData components PersistForecasts method
state.TriggerOnPersisting();
// Assert that state was saved and there is a non-empty forecast array returned
var didSaveState = state.TryTake("weather-data", out var savedState);
Assert.IsTrue(didSaveState);
Assert.NotEmpty(savedState);
```
--------------------------------
### Implementing a Fallback Service Provider
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Implement the `IServiceProvider` interface to create a custom fallback service provider. This allows for alternative IoC containers or automatic mock service creation.
```csharp
public class FallbackServiceProvider : IServiceProvider
{
public object GetService(Type serviceType)
{
return new DummyService();
}
}
public class DummyService
```
--------------------------------
### Mock Component with Moq
Source: https://bunit.dev/docs/providing-input/substituting-components.html
Substitute a component with a mock object created using the Moq library. This provides fine-grained control over the mocked component's behavior.
```csharp
[Fact]
public void Foo_Doesnt_Have_A_Bar_But_Mock()
{
// Register the mock instance for Bar
Mock barMock = new Mock();
ComponentFactories.Add(barMock.Object);
// Render the component under test
RenderedFragment cut = Render(@);
// Verify that the Bar component has
// been substituted in the render tree
RenderedComponent bar = cut.FindComponent();
Assert.Same(barMock.Object, bar.Instance);
}
```
--------------------------------
### Create new NUnit test project manually
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new NUnit test project manually. Replace with your desired project name.
```bash
dotnet new nunit -o
```
--------------------------------
### Extension Method for Dynamic Mock Creation
Source: https://bunit.dev/docs/providing-input/substituting-components.html
An extension method to dynamically create mock components using Moq's MockRepository and reflection.
```csharp
// Extension method that can create mock components dynamically
// based on a type.
internal static class MockRepositoryExtensions
{
private static readonly MethodInfo CreateMethodInfo = typeof(MockRepository)
.GetMethod(nameof(MockRepository.Create), Array.Empty());
public static IComponent CreateComponent(this MockRepository repository, Type type)
{
var genericCreateMethod = CreateMethodInfo.MakeGenericMethod(type);
var mock = (Mock)genericCreateMethod.Invoke(repository, null);
return (IComponent)mock.Object;
}
}
```
--------------------------------
### Basic xUnit Test in .razor File
Source: https://bunit.dev/docs/getting-started/writing-tests.html
A simple xUnit test written in a .razor file. It renders a component and asserts its markup using MarkupMatches.
```razor
@inherits BunitContext
@code
{
[Fact]
public void HelloWorldComponentRendersCorrectly()
{
// Act
var cut = Render(@);
// Assert
cut.MarkupMatches(@
Hello world from Blazor
);
}
}
```
--------------------------------
### Register Mock Component Factory with NSubstitute
Source: https://bunit.dev/docs/providing-input/substituting-components.html
Use this to replace multiple instances of a specific component type with a mock created by NSubstitute.
```csharp
// Register a mock component factory to replace multiple Bar components
ComponentFactories.Add(() => Substitute.For());
```
--------------------------------
### Register Mock Component Factory with MOQ
Source: https://bunit.dev/docs/providing-input/substituting-components.html
Use this to replace multiple instances of a specific component type with a mock created by MOQ.
```csharp
// Register a mock component factory to replace multiple Bar components
ComponentFactories.Add(() => Mock.Of());
```
--------------------------------
### Using AutoMocker as Fallback Service Provider
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Implement a fallback service provider using AutoMocker to automatically create mock services. This is useful for scenarios where you need mock dependencies without explicit configuration.
```csharp
using Bunit;
using Moq.AutoMock;
using Xunit;
public class MockServiceProviderTests : TestContext
{
public class MockServiceProvider : IServiceProvider
{
private readonly AutoMocker _autoMocker = new AutoMocker();
public object? GetService(Type serviceType)
{
return _autoMocker.Get(serviceType);
}
}
[Fact]
public void UseMockServiceProvider()
{
Services.AddSingleton();
Services.AddTransient();
Services.UseServiceProviderFactory(new MockServiceProvider());
var service = Services.GetService();
Assert.NotNull(service);
}
}
public class SomeService
{
public SomeService(IDisposable dependency)
{
}
}
```
--------------------------------
### Set Authenticating and Authorizing State
Source: https://bunit.dev/docs/test-doubles/auth.html
Call `AddAuthorization()` and then `SetAuthorizing()` on the returned context to simulate an authenticating state. This is useful for testing loading indicators.
```csharp
// Arrange
var authContext = AddAuthorization();
authContext.SetAuthorizing();
// Act
var cut = Render();
// Assert
cut.MarkupMatches(@"
Please log in!
State: Authorizing
");
```
--------------------------------
### Create new MSTest test project manually
Source: https://bunit.dev/docs/getting-started/create-test-project.html
Create a new MSTest test project manually. Replace with your desired project name.
```bash
dotnet new mstest -o
```
--------------------------------
### Emulate FocusAsync JSInterop
Source: https://bunit.dev/docs/test-doubles/emulating-ijsruntime.html
Test the `FocusAsync` method on `ElementReference` by registering invocations and verifying they occurred with the correct arguments. This snippet shows how to trigger the focus and then verify the JSInterop call.
```razor
@code {
private ElementReference exampleInput;
private async Task ChangeFocus()
{
await exampleInput.FocusAsync();
}
}
```
```csharp
var cut = Render();
var inputElement = cut.Find("input");
cut.Find("button").Click(); // Triggers onclick handler that sets focus of input element
JSInterop.VerifyFocusAsyncInvoke()
.Arguments[0]
.ShouldBeElementReferenceTo(inputElement);
```
--------------------------------
### Pass Component with Parameters to ChildContent (C#)
Source: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html
Demonstrates passing a component with its own parameters (e.g., `` with `Heading` and `Type`) to the `ChildContent` parameter. It uses a nested `ComponentParameterCollectionBuilder` to configure the child component.
```csharp
public class ChildContentParams3Test : BunitContext
{
[Fact]
public void Test()
{
var cut = Render(parameters => parameters
.AddChildContent(alertParameters => alertParameters
.Add(p => p.Heading, "Alert heading")
.Add(p => p.Type, AlertType.Warning)
.AddChildContent("
Hello World
")
)
);
}
}
```
--------------------------------
### Test for Simulating Interactive Server Rendering
Source: https://bunit.dev/docs/interaction/render-modes.html
Tests a component's behavior during interactive server rendering by setting `RendererInfo` to interactive. This verifies the 'Hey I am your assistant' message.
```csharp
[Fact]
public void SimulatingInteractiveServerRendering()
{
// Arrange
SetRendererInfo(new RendererInfo(rendererMode: "Server", isInteractive: true));
// Act
var cut = Render();
// Assert
cut.MarkupMatches("
Hey I am your assistant
");
}
```
--------------------------------
### Stub Components with Markup or RenderFragment
Source: https://bunit.dev/docs/providing-input/substituting-components.html
Replace matching components with custom HTML markup or a RenderFragment. This allows for static content or dynamically generated content as a substitute.
```csharp
// Add the markup specified in the string to the rendered output
// instead of the components that match the predicate,
ComponentFactories.AddStub(type => type.Namespace == "Third.Party.Lib",
"
NOT FROM BAR
");
// Add the markup produced by the render fragment to the rendered
// output instead of the components that match the predicate.
ComponentFactories.AddStub(type => type.Namespace == "Third.Party.Lib",
@
NOT FROM BAR
);
```
--------------------------------
### Using Custom Service Provider via delegate with bUnit
Source: https://bunit.dev/docs/providing-input/inject-services-into-components.html
Register a custom service provider using a delegate. This approach allows for direct instantiation and configuration of a custom service provider within bUnit tests.
```csharp
using Bunit;
using Xunit;
public class CustomDelegateTests : TestContext
{
[Fact]
public void UseCustomServiceProviderViaDelegate()
{
Services.UseServiceProviderFactory(x => new CustomServiceProvider(x));
var dummyService = Services.GetService();
Assert.NotNull(dummyService);
}
}
```
--------------------------------
### Find DOM elements using CSS selectors
Source: https://bunit.dev/docs/verification/verify-markup.html
Use Find and FindAll to query rendered HTML elements by CSS selectors. Find returns a single element or throws, while FindAll returns a list. Always prefer Find for single elements as it auto-refreshes.
```csharp
var tableCaption = cut.Find("caption");
var tableCells = cut.FindAll("td:first-child");
Assert.Empty(tableCaption.Attributes);
```
```csharp
Assert.All(tableCells, td => td.HasAttribute("style"));
}
}
```
--------------------------------
### Pass Mix of Markup and Component to RenderFragment (C#)
Source: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html
Combine markup and components within a RenderFragment by chaining Add() and Add() methods on the parameter builder.
```csharp
public class RenderFragmentParams4Test : BunitContext
{
[Fact]
public void Test()
{
var cut = Render(parameters => parameters
.Add(p => p.Content, "
")
)
);
}
}
```
--------------------------------
### Check for Persisted Data
Source: https://bunit.dev/docs/test-doubles/persistentcomponentstate.html
Use the `TryTake` method to check if data has been persisted under a specific key. This is useful for asserting that state was correctly saved or retrieved.
```csharp
var state = AddBunitPersistentComponentState();
var key = "STATE KEY";
// render component, call TriggerOnPersisting
bool foundState = state.TryTake(key, out var data);
```
--------------------------------
### Essential Imports for .razor Tests
Source: https://bunit.dev/docs/getting-started/writing-tests.html
Include these using statements in your _Imports.razor file for bUnit testing. They provide necessary namespaces for Blazor, bUnit, and testing utilities.
```razor
@using Microsoft.AspNetCore.Components.Forms
@using Microsoft.AspNetCore.Components.Web
@using Microsoft.JSInterop
@using Microsoft.Extensions.DependencyInjection
@using AngleSharp.Dom
@using Bunit
@using Bunit.TestDoubles
```
--------------------------------
### Setting Base Address
Source: https://bunit.dev/docs/test-doubles/fake-webassemblyhostenvironment.html
This snippet demonstrates how to set a custom base address for the IWebAssemblyHostEnvironment. The BaseAddress property can be directly assigned a new value.
```csharp
// Arrange
var hostEnvironment = Services.GetRequiredService();
// Sets a new base address directly on the BaseAddress property.
hostEnvironment.BaseAddress = "myBaseUrl/";
// Act
var cut = Render();
// Assert - inspect markup to verify that the BaseAddress is used correctly.
cut.Find("#address").MarkupMatches("
The base URL is: myBaseUrl/
");
```
--------------------------------
### Basic bUnit Test with xUnit
Source: https://bunit.dev/docs/getting-started/writing-tests.html
A fundamental bUnit test written using the xUnit framework. It inherits from BunitContext and uses MarkupMatches to assert the rendered output.
```csharp
using Xunit;
using Bunit;
public class HelloWorldTest : BunitContext
{
[Fact]
public void HelloWorldComponentRendersCorrectly()
{
// Act
var cut = Render();
// Assert
cut.MarkupMatches("
Hello world from Blazor
");
}
}
```
--------------------------------
### Add bUnit's PersistentComponentState
Source: https://bunit.dev/docs/test-doubles/persistentcomponentstate.html
Call this extension method on `BunitContext` to enable testing of components using `PersistentComponentState`. It returns a `BunitPersistentComponentState` instance.
```csharp
var state = AddBunitPersistentComponentState();
```
--------------------------------
### Pass Component with Parameters to RenderFragment (C#)
Source: https://bunit.dev/docs/providing-input/passing-parameters-to-components.html
Use the Add method to pass a component with parameters to a RenderFragment. The second argument can be a lambda to configure the child component's parameters.
```csharp
public class RenderFragmentParams3Test : BunitContext
{
[Fact]
public void Test()
{
var cut = Render(parameters => parameters
.Add(p => p.Content, alertParameters => alertParameters
.Add(p => p.Heading, "Alert heading")
.Add(p => p.Type, AlertType.Warning)
.AddChildContent("