I'm using Radzen in my Blazor project and I decided to learn to write tests with bUnit. However, I'm encountering difficulties.
Sometimes a random id is assigned to elements generated by Radzen components. This results in a mismatch when I compare the result of the test with what I expect it to be.
For example, I have a component called DefaultProcessingTemplate.razor:
@using ClientProcessing.Library
@inject IJSRuntime JsRuntime
//@inject DialogService DialogService
@if (ClientProcessor as IDataProcessing is not null)
{
<RadzenRow>
<RadzenHeading Size="H2" Text="Reporting"></RadzenHeading>
</RadzenRow>
<RadzenRow Gap=".5rem" class="rz-mb-6">
<RadzenButton Click="OpenReportingRunDialog" ButtonStyle="ButtonStyle.Primary" Text="Run"></RadzenButton>
<RadzenButton Click="OpenReportingDownloadDialog" ButtonStyle="ButtonStyle.Primary" Text="Download"></RadzenButton>
</RadzenRow>
}
else
{
// code ...
}
@code {
private DialogOptions defaultDialogOptions = new DialogOptions { CloseDialogOnEsc = true, Width = "900px" };
[Parameter]
public IDataProcessing ClientProcessor { get; set; }
protected override void OnInitialized()
{
// ... code
}
private async Task OpenReportingRunDialog()
{
var parameters = new Dictionary<string, object>()
{
{ "CommDate", ClientProcessor.GetCurrMo() },
{ "Reporting", ClientProcessor }
};
//await DialogService.OpenAsync<ReportingRun>("Run", parameters, defaultDialogOptions);
}
private async Task OpenReportingDownloadDialog()
{
var reporting = ClientProcessor as IReporting;
var parameters = new Dictionary<string, object> { { "FilePaths", reporting.GetReportPaths() } };
var options = new DialogOptions
{
CloseDialogOnEsc = true,
Width = "1200px"
};
//await DialogService.OpenAsync<DownloadFiles>("Download", parameters, options);
}
}
I want to test that if the ClientProcessor
parameter is not null, DefaultProcessingTemplate
component contains the <RadzenHeading Size="H2" Text="Processing"></RadzenHeading>
element. The following is the best I have come up with to test this.
DefaultProcessingTemplateTests.razor:
@using ClientProcessing.BlazorServer.Components.Shared
@using ClientProcessing.Library
@using Moq
@using Radzen.Blazor
@inherits TestContext
@code {
private readonly Mock<IDataProcessing> _mockDatabaseProcessing = new Mock<IDataProcessing>();
[Fact]
public void HasSection()
{
var cut = Render(@<DefaultProcessingTemplate ClientProcessor="_mockDatabaseProcessing.Object" />);
cut.Find("h2").MarkupMatches(@<RadzenHeading Size="H2" Text="Reporting"></RadzenHeading>);
}
}
As a result of those randomly generated ids, the test fails:
Message:
Bunit.HtmlEqualException : HTML comparison failed.
The following errors were found:
1: The values of the attributes at h2(0)[id] are different.
Actual HTML:
<h2 class="rz-heading" id="4KjgjHwknU" >Reporting</h2>
Expected HTML:
<h2 class="rz-heading" id="cHelqcQDgU" >Reporting</h2>
How can I write tests for Blazor components that use Radzen? Is there a convenient way to do this?
Bunit allows you to customize how markup is compared, see https://bunit.dev/docs/verification/semantic-html-comparison.html
However, in this case you are essentially testing Radzons components which I don't recommend, tightly coupling your test to a Radzons implementation detail (the markup their component produces) instead of their public api surface.
What you probably want to test here is that there is an expected child component (RadzenHeading
) of your component under test, and that the expected parameters was passed to it, e.g.:
var rh = cut.FindComponent<RadzenHeading>();
Assert.Equal("H2", rh.Instance.Size);
Assert.Equal("Heading", rh.Instance.Text);