为 Blazor 组件单元测试模拟 IJSRuntime

Mocking IJSRuntime for Blazor Component unit tests

按照 this prototype 进行单元测试后,我 运行 在使用 JS 互操作时遇到了问题。

[Test]
public void ExampleTest()
{
    var component = host.AddComponent<MyComponent>();
}

仅仅添加一个使用了IJSRuntime的组件会导致下面的异常

System.InvalidOperationException : Cannot provide a value for property 'JsRuntime' on type 'Application.Components.MyComponent'. There is no registered service of type 'Microsoft.JSInterop.IJSRuntime'.

JS 互操作没有做任何有趣的事情,它只是一个关注元素的 void 函数 - 我不关心测试它,我只想能够继续为组件本身编写测试.

如何使用 Moq 模拟 IJSRuntime?

当我尝试

[Test]
public void ExampleTest()
{
    var jsRuntimeMock = new Mock<IJSRuntime>();

    host.AddService(jsRuntimeMock);

    var component = host.AddComponent<MyComponent>();
}

我仍然遇到异常

host.AddService(jsRuntimeMock);

Mock<IJSRuntime> 注册为依赖项。

在实现中(在测试程序集之外)没有 类 应该有这样的依赖性,但这是一个常见的错误。

使用 Mock<T> 属性 ObjectIJSRuntime 注册为依赖项,其中包含对实现接口的对象的引用。

像这样:

host.AddService(jsRuntimeMock.Object);

Microsoft 使用大量内部单例,因此在应用程序级别进行测试非常非常困难,您应该替换所有默认服务,如 IJSRuntime、NavigationManager 和 NavigationInterceptor。我希望在下一个预览中会有一种简单的方法来创建单元测试方法并模拟浏览器。