如何为Dispatcher调用的自定义WPF MessageBox编写单元测试?
问题分析与解决方案
核心问题
你的自定义WPF MessageBox通过Dispatcher.BeginInvoke异步调用,调试时能命中Show()方法,但单元测试无法捕获该调用,主要原因有两点:
- 验证代码的写法错误,混淆了返回值设置与调用验证的语法
- Dispatcher异步操作的处理可能存在遗漏
步骤1:修正单元测试的验证逻辑
你当前的cVM.Returns(1).Show();写法不符合NSubstitute的语法:
Returns(1)是用来设置方法的返回值,需要写在方法调用之后- 验证方法是否被调用,应该使用
Received()
修正后的测试代码片段:
public void CustomMBTest() { Application app = new Application(); ICustomMessageBoxView cVM = Substitute.For<ICustomMessageBoxView>(); // 先设置Show方法的返回值(如果需要) cVM.Show().Returns(1); CustomMssageBoxBuilder cMB = new CustomMssageBoxBuilder(cVM); WPFMessageBoxService.BuildCustomMessageBox.Returns(cMB); vm.Foo(true); DoEvents(); // 验证Show方法是否被调用过 cVM.Received().Show(); }
步骤2:确保Dispatcher异步操作完全执行
你的DoEvents方法可能没有彻底处理完Dispatcher队列中的异步操作,可以尝试调整实现:
public void DoEvents() { var frame = new DispatcherFrame(); Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => { frame.Continue = false; })); Dispatcher.PushFrame(frame); }
这种方式会让Dispatcher优先处理完队列中所有优先级高于Background的操作,确保你的BeginInvoke回调被执行。
步骤3:检查依赖注入的正确性
确认vm中的_wpfMB字段确实是你在测试中替换的WPFMessageBoxService实例,避免出现依赖未正确注入的情况。
内容的提问来源于stack exchange,提问作者OmniStack
相关产品推荐
相关产品推荐

