Back to Devexpress

Test Components with bUnit

blazor-404603-common-concepts-test-components-with-bunit.md

latest4.9 KB
Original Source

Test Components with bUnit

  • Jul 06, 2025
  • 3 minutes to read

This article shows how you can add unit testing to your Blazor application. The testing framework is bUnit. The example tests a custom component that contains DevExpress Blazor UI components.

View Example: Test DevExpress Blazor components with bUnit

Important

The DevExpress support team cannot assist you with testing environment setup. For additional information, please review Limitations on DevExpress Support Services. If you experience issues, make sure that your testing environment works without DevExpress components. Try looking for a solution in online resources such as StackOverflow or bUnit forum.

Follow the steps below to run bUnit tests in a project that includes DevExpress Blazor components:

  1. Set up a project in which to add tests. The following resources may be helpful:

  2. In the new project, create a class and reference the DevExpress.Blazor.Internal namespace.

  3. Copy all class members from the following GitHub repository: https://github.com/DevExpress-Examples/blazor-bunit-tests. These members mock internal dependencies so that it is possible to render our Blazor components with bUnit.

  4. You can now write tests. We recommend that you use public API to test your usage scenarios instead of relying on the component internal structure as it may change after you upgrade project dependencies.

The following snippet renders a Blazor component that contains DxGrid and DxTreeView, and checks that the Grid component applies the filter after a user selects a TreeView node:

csharp
using Bunit;
using DxTestProject.Pages;
using System;
using Xunit;
using Microsoft.Extensions.DependencyInjection;
using DevExpress.Blazor;

namespace DevExpressBunit.Test {
    public class GridApplyFilter : IDisposable {
        public TestContext Context { get; }
        public GridApplyFilter() {
            Context = new TestContext();
            Context.Services.AddOptions();
            Context.AddDevExpressBlazorTesting();
        }
        [Fact]
        public void CheckIfNodeClickAppliesFilter() {
            // Render the component with DevExpress Blazor components
            var cut = Context.RenderComponent<Grid_ApplyFilter>();
            // Obtain an instance of DxTreeView and DxGrid
            var treeview = cut.FindComponent<DxTreeView>().Instance;
            var grid = cut.FindComponent<DxGrid>().Instance;
            // Select a node and check the number of rows currently displayed in the Grid
            cut.InvokeAsync(() => treeview.SelectNode(x => x.Text == "Filter by date"));
            Assert.Equal(1, grid.GetVisibleRowCount());
            cut.InvokeAsync(() => treeview.SelectNode(x => x.Text == "Filter by temperature"));
            Assert.Equal(3, grid.GetVisibleRowCount());
            cut.InvokeAsync(() => treeview.SelectNode(x => x.Text == "Filter by precipitation"));
            Assert.Equal(6, grid.GetVisibleRowCount());
        }
        public void Dispose() {
            Context.Dispose();
        }
    }
}
razor
<DxTreeView AllowSelectNodes="true"
            SelectionChanged="TreeView_SelectionChanged">
    <Nodes>
        <DxTreeViewNode Text="Filter by date" />
        <DxTreeViewNode Text="Filter by temperature" />
        <DxTreeViewNode Text="Filter by precipitation" />
    </Nodes>
</DxTreeView>

<DxGrid Data="@forecasts" @ref="MyGrid">
    <Columns>
        <DxGridDataColumn FieldName="Date" />
        <DxGridDataColumn FieldName="TemperatureC" Caption="Temperature" />
        <DxGridDataColumn FieldName="Precipitation" />
    </Columns>
</DxGrid>

@code {
    IGrid MyGrid { get; set; }

    private WeatherForecast[] forecasts;

    void TreeView_SelectionChanged(TreeViewNodeEventArgs e) {
        MyGrid.SetFilterCriteria(null);
        switch(e.NodeInfo.Text) {
            case "Filter by date":
                MyGrid.FilterBy("Date", GridFilterRowOperatorType.Equal, new DateTime(2020, 05, 14)); break; // the Grid displays 1 row
            case "Filter by temperature":
                MyGrid.FilterBy("TemperatureC", GridFilterRowOperatorType.Greater, 20); break; // the Grid displays 3 rows
            case "Filter by precipitation":
                MyGrid.FilterBy("Precipitation", GridFilterRowOperatorType.Less, 2); break; // the Grid displays 6 rows
        }
    }

    protected override void OnInitialized() {
        forecasts = ForecastService.GetForecastAsync();
    }
}