You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Blazor单元测试:用Moq、bUnit、xUnit验证JS函数调用失败排查

问题原因及解决方法

你的测试失败主要有三个关键问题,逐一拆解:

1. 手动实例化组件导致bUnit无法跟踪JS调用

你直接通过new CreateParticipant(...)创建组件实例,没有使用bUnit的ctx.RenderComponent<CreateParticipant>()方法。这种情况下,bUnit的ctx.JSInterop无法捕获到组件对IJSRuntime的调用——组件用的是你手动传入的Mock实例,而非bUnit上下文提供的JSInterop。

2. 参数传递不匹配

测试中定义了变量elementId = "personal-details",但调用AnchorOnClickAsync时传的是字符串字面量"elementId",导致实际调用JS函数时的参数是"elementId",而非预期的"personal-details",断言自然不匹配。

3. Mock实例变量名错误

你声明了var jsRuntime = new Mock<IJSRuntime>(),但创建组件时用的是jsRuntimeMock.Object,变量名不一致属于笔误,会导致使用未初始化的Mock(如果jsRuntimeMock未定义),或者完全用错了Mock实例。


修正后的测试代码

[Fact]
public async Task MyComponent_Calls_ScrollIntoView()
{
    // Arrange
    var targetElementId = "personal-details";
    var ctx = new Bunit.TestContext();

    // 创建IJSRuntime的Mock实例
    var jsRuntimeMock = new Mock<IJSRuntime>();
    // 设置Mock返回值,模拟JS函数返回true
    jsRuntimeMock
        .Setup(x => x.InvokeAsync<bool>(
            "scrollIntoView", 
            It.IsAny<object[]>()))
        .ReturnsAsync(true);

    // 将Mock注册到bUnit上下文的服务容器
    ctx.Services.AddSingleton(jsRuntimeMock.Object);

    // 通过bUnit渲染组件,确保组件使用上下文内的Mock服务
    var cut = ctx.RenderComponent<CreateParticipant>(parameters => parameters
        .Add(p => p.MainLayoutService, mockMainLayoutService.Object)
        .Add(p => p.ParticipantService, mockIParticipantService.Object)
        .Add(p => p.Snackbar, mockSnackbar.Object)
        .Add(p => p.LookupService, mockLookupService.Object)
        .Add(p => p.NavigationManager, ctx.Services.GetRequiredService<FakeNavigationManager>())
    );

    // Act
    await cut.Instance.AnchorOnClickAsync(targetElementId);

    // Assert:用Moq的Verify验证Mock的调用情况
    jsRuntimeMock.Verify(x => x.InvokeAsync<bool>(
        "scrollIntoView", 
        It.Is<object[]>(args => args[0].ToString() == targetElementId)), 
        Times.Once);
}

关键修正点说明

  • 使用ctx.RenderComponent<CreateParticipant>()渲染组件,确保组件依赖的服务(包括IJSRuntime的Mock)来自bUnit上下文。
  • 调用AnchorOnClickAsync时传入正确的变量targetElementId,而非字面量字符串。
  • 用Moq的Verify方法直接验证你创建的jsRuntimeMock实例的调用情况,而非依赖bUnit的ctx.JSInterop(因为组件用的是手动注册的Mock)。

内容的提问来源于stack exchange,提问作者hanushi-thana

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 02:20:26