The class BlazorUnitTest
provides helpers/test context dedicated for unit tests for the blazor component. It also avoids code duplication of unit test classes.
[TestFixture]publicclassProductDetailTests:BlazorUnitTest{publicoverridevoidSetup(){// Don't forget the method base.Setup() to initialize existing helpersbase.Setup();}}
[TestFixture]publicclassProductDetailTests:BlazorUnitTest{// Declare the mock of IProductServiceprivateMock<IProductService>productServiceMock;publicoverridevoidSetup(){base.Setup();// Intialize the mock of IProductServicethis.productServiceMock=MockRepository.Create<IProductService>();// Add the mock of IProductService as a singleton for resolution _=Services.AddSingleton(this.productServiceMock.Object);}}
Info
After configuring the test class setup, you can start implementing unit tests.
Below is an example of a a unit test that checks whether the GetProduct method of the serivce ProductService service
was called after the component was initialized:
[TestFixture]publicclassProductDetailTests:BlazorUnitTest{...[Test]publicvoidOnInitializedAsync_GetProduct_ProductIsRetrieved(){// ArrangevarexpectedProduct=Fixture.Create<Product>();// Setup mock of GetProduct of the service ProductService_=this.productServiceMock.Setup(service=>service.GetProduct(expectedProduct.Id)).ReturnsAsync(expectedProduct);// Act// Render the component ProductDetail with the required ProductId parametervarcut=RenderComponent<ProductDetail>(ComponentParameter.CreateParameter("ProductId",expectedProduct.Id));// You can wait for a specific element to be rendered before assertions using a css selector, for example the DOM element with id product-id_=cut.WaitForElement("#product-id");// Assert// Assert that all mocks setups have been calledcut.WaitForAssertion(()=>MockRepository.VerifyAll());}}
Tip
WaitForAssertion is useful in asserting asynchronous changes: It will blocks and waits in a
test method until the specified assertion action does not throw an exception, or until the timeout is reached (the default
timeout is one second). Assertion of asynchronous changes
Tip
Within unit tests on Blazor components, you can interact with HTML DOM and query rendered HTMLelements (buttons, div...) by using
CSS selectors (id, class...) Lean more about CSS selectors
How to unit test a component requiring an external component¶
Some components proposed by MudBlazor (MudAutocomplete, MudSelect...) use another component MudPopoverProvider to display elements.
If in a unit test that uses these MudBlazor components, the MudPopoverProvider component is not rendered, the interactions with these components are restricted.
Let us start with the following example:
Example of the content of the component SearchState
<MudAutocompleteT="string"Label="US States"@bind-Value="selectedState"SearchFunc="@Search"/>@code{privatestringselectedState;privatestring[]states={"Alabama","Colorado","Missouri","Wisconsin"}privateasyncTask<IEnumerable<string>>Search(stringvalue){// In real life use an asynchronous function for fetching data from an api.awaitTask.Delay(5);// if text is null or empty, show complete listif(string.IsNullOrEmpty(value))returnstates;returnstates.Where(x=>x.Contains(value,StringComparison.InvariantCultureIgnoreCase));}}
We want to test the search when a user interacts with the MudAutocomplete component to search for the state Wisconsin:
[TestFixture]publicclassSearchStateTests:BlazorUnitTest{...[Test]publicvoidSearch_UserSearchAndSelectState_StateIsSelected(){// ArrangevaruserQuery="Wis";// First render MudPopoverProvider componentvarpopoverProvider=RenderComponent<MudPopoverProvider>();// Second, rendrer the component SearchState (under unit test)varcut=RenderComponent<SearchState>();// Find the MudAutocomplete component within SearchState componentvarautocompleteComponent=cut.FindComponent<MudAutocomplete<string>>();// Fire click event on, autocompleteComponent.Find("input").Click();autocompleteComponent.Find("input").Input(userQuery);// Wait until the count of element in the list rendred on the component MudPopoverProvider is equals to onepopoverProvider.WaitForAssertion(()=>popoverProvider.FindAll("div.mud-list-item").Count.Should().Be(1));// Act// Get the only element present on the listvarstateElement=popoverProvider.Find("div.mud-list-item");// Fire click event on the elementstateElement.Click();// Assert// Check if the MudAutocomplete compoment has been closed after the click eventcut.WaitForAssertion(()=>autocompleteComponent.Instance.IsOpen.Should().BeFalse());...}}