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

如何为Blazor WebAssembly的PDF下载功能编写Bunit单元测试?

如何为Blazor WebAssembly的PDF下载按钮编写BUnit单元测试?

针对你的PDF下载功能,单元测试的核心是验证C#逻辑是否正确触发了依赖调用——也就是确认API方法被调用,且JSInterop参数传递无误。不需要测试JavaScript函数的内部PDF生成逻辑(那属于前端测试范畴)。

测试前的准备

  1. 确保组件中下载按钮的点击事件绑定了generateServiceAgreement方法,示例代码如下:
    <button @onclick="generateServiceAgreement">下载协议</button>
    
  2. 将planOfService抽象为接口(比如IPlanOfService)并通过依赖注入引入,方便测试时Mock。

具体测试场景及代码

场景1:点击按钮时正确调用API获取协议文本

using Bunit;
using Moq;
using Xunit;

public class DownloadButtonTests : TestContext
{
    [Fact]
    public async Task ClickingDownloadButton_CallsSavePlanOfServiceApi()
    {
        // Arrange
        var mockPlanService = new Mock<IPlanOfService>();
        mockPlanService.Setup(x => x.SavePlanOfService())
                       .ReturnsAsync("<html><body>协议内容</body></html>");
        
        // 注入Mock服务
        Services.AddSingleton(mockPlanService.Object);
        
        // 渲染目标组件
        var cut = RenderComponent<YourComponent>();

        // Act
        cut.Find("button").Click();
        await Task.Delay(100); // 等待异步操作完成

        // Assert
        mockPlanService.Verify(x => x.SavePlanOfService(), Times.Once);
    }
}

场景2:获取文本后正确调用JS下载函数并传递正确参数

[Fact]
public async Task GenerateServiceAgreement_CallsBlazorDownloadFileWithCorrectParams()
{
    // Arrange
    var expectedText = "<html><body>协议内容</body></html>";
    var mockPlanService = new Mock<IPlanOfService>();
    mockPlanService.Setup(x => x.SavePlanOfService())
                   .ReturnsAsync(expectedText);
    
    Services.AddSingleton(mockPlanService.Object);
    
    // 监听JSInterop调用
    var jsInterop = JSInterop.SetupVoid("BlazorDownloadFile")
                            .SetVoidResult();
    
    var cut = RenderComponent<YourComponent>();

    // Act
    cut.Find("button").Click();
    await Task.Delay(100);

    // Assert
    // 验证JS函数被调用,且参数匹配预期:文件名和协议文本
    jsInterop.VerifyInvoke().Arguments.ShouldBeEquivalentTo(new object[] { "Service_Agreement.pdf", expectedText });
}

场景3:处理API调用失败的情况(可选)

[Fact]
public async Task SavePlanOfServiceThrowsException_DoesNotCallJsDownload()
{
    // Arrange
    var mockPlanService = new Mock<IPlanOfService>();
    mockPlanService.Setup(x => x.SavePlanOfService())
                   .ThrowsAsync(new HttpRequestException("API调用失败"));
    
    Services.AddSingleton(mockPlanService.Object);
    
    var jsInterop = JSInterop.SetupVoid("BlazorDownloadFile");
    
    var cut = RenderComponent<YourComponent>();

    // Act & Assert
    await Assert.ThrowsAsync<HttpRequestException>(() => cut.Find("button").ClickAsync());
    jsInterop.VerifyInvoke(Times.Never);
}

关键说明

  • Mock依赖:用Moq模拟IPlanOfService的返回值或异常,避免测试依赖真实API服务。
  • JSInterop验证:BUnit自带的JSInterop工具可以监听C#对JavaScript函数的调用,确保参数传递准确。
  • 异步处理:因为方法是异步执行的,测试时需要等待操作完成(可通过Task.Delay或直接等待ClickAsync的返回值)。

内容的提问来源于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 05:10:18