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

如何使用Moq模拟并配置MudBlazor.IDialogService的DialogResult?

解决Blazor WASM单元测试中MudBlazor IDialogService模拟返回null的问题

问题根源

你的测试代码存在两个核心问题:

  1. 同时创建了Mock<IDialogService>却又注册了真实的DialogService,导致组件可能注入真实服务而非Mock实例
  2. 未对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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 17:35:30