### 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.0 enable false ``` -------------------------------- ### 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

Hello @(HostEnvironment.IsDevelopment() ? "Developers" : "World").

The base URL is: @HostEnvironment.BaseAddress

``` -------------------------------- ### 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.0 enable false Exe runtime; build; native; contentfiles; analyzers; buildtransitive all ``` -------------------------------- ### 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.0 enable false ``` -------------------------------- ### 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.0 enable false false ``` -------------------------------- ### 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.0 enable false runtime; build; native; contentfiles; analyzers; buildtransitive all ``` -------------------------------- ### 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:

    @foreach (var claim in @context.User.FindAll(x => x.Type != ClaimTypes.Name && x.Type != ClaimTypes.Role)) {
  • @GetClaimName(claim): @claim.Value
  • }
  • You have the role SUPER USER
  • You have the role ADMIN
  • You are a CONTENT EDITOR
  • @if(context.User.Identity?.AuthenticationType == "custom-auth-type") {
  • You have the authentication type CUSTOM AUTH TYPE
  • }
@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 @result @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, "

Below you will find a most interesting alert!

") .Add(p => p.Content, childParams => childParams .Add(p => p.Heading, "Alert heading") .Add(p => p.Type, AlertType.Warning) .AddChildContent("

Hello World

") ) ); } } ``` -------------------------------- ### 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("

Hello World

") ) ); } } ```