如何为Blazor WebAssembly的PDF下载功能编写Bunit单元测试?
如何为Blazor WebAssembly的PDF下载按钮编写BUnit单元测试?
针对你的PDF下载功能,单元测试的核心是验证C#逻辑是否正确触发了依赖调用——也就是确认API方法被调用,且JSInterop参数传递无误。不需要测试JavaScript函数的内部PDF生成逻辑(那属于前端测试范畴)。
测试前的准备
- 确保组件中下载按钮的点击事件绑定了
generateServiceAgreement方法,示例代码如下:<button @onclick="generateServiceAgreement">下载协议</button> - 将
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
相关产品推荐
相关产品推荐

