如何使用Moq模拟并配置MudBlazor.IDialogService的DialogResult?
解决Blazor WASM单元测试中MudBlazor IDialogService模拟返回null的问题
问题根源
你的测试代码存在两个核心问题:
- 同时创建了
Mock<IDialogService>却又注册了真实的DialogService,导致组件可能注入真实服务而非Mock实例 - 未对Mock的
Show<T>方法设置返回值,调用时自然返回null
正确配置步骤
1. 模拟IDialogReference及DialogResult
组件调用Show后会获取IDialogReference并等待其Result,因此需要先模拟这两个对象:
// 模拟用户点击确认按钮的结果,也可改为DialogResult.Cancel()模拟取消 var mockDialogResult = DialogResult.Ok(true); // 模拟IDialogReference,设置Result为已完成的Task var mockDialogRef = new Mock<IDialogReference>(); mockDialogRef.SetupGet(x => x.Result).Returns(Task.FromResult(mockDialogResult));
2. 配置IDialogService的Mock行为
指定Show<ConfirmationDialog>方法返回我们模拟的IDialogReference:
var mockDialogService = new Mock<IDialogService>(); // 匹配任意参数的Show<ConfirmationDialog>调用,返回模拟的对话框引用 mockDialogService .Setup(s => s.Show<ConfirmationDialog>( It.IsAny<string>(), It.IsAny<DialogParameters>(), It.IsAny<DialogOptions>() )) .Returns(mockDialogRef.Object);
3. 修正测试上下文配置
移除真实DialogService的注册,确保组件使用Mock实例:
var ctx = new Bunit.TestContext(); // 注册Mock的IDialogService到测试上下文 ctx.Services.AddScoped(_ => mockDialogService.Object); // 渲染组件(如果是构造注入,也可直接传入mock实例) var cut = ctx.RenderComponent<Participant>();
关键注意事项
- 务必删除
ctx.Services.AddScoped<IDialogService, DialogService>();这行代码,避免真实服务覆盖Mock - 可根据测试场景调整
DialogResult的返回值,模拟用户不同操作(确认/取消) - 如果组件通过构造函数注入
IDialogService,直接传递mockDialogService.Object即可,无需注册到测试上下文
内容的提问来源于stack exchange,提问作者hanushi-thana
相关产品推荐
相关产品推荐

