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

使用Moq进行单元测试时如何绕过自定义MessageBox弹窗

问题原因与解决方案

1. 依赖注入未正确实现(最可能的核心原因)

你需要先确认ClassicSudokuViewModel的构造函数中,是否将传入的IMessageBoxService实例赋值给了类内部调用的MessageBoxService成员。如果你的ViewModel内部是直接实例化了真实的MessageBoxService实现类,而非使用注入的对象,那么你构造的Mock对象根本不会被调用,自然会弹出真实窗口。
错误的ViewModel实现示例:

// 错误:直接初始化真实服务,注入的mock实例不会被使用
public class ClassicSudokuViewModel
{
    public IMessageBoxService MessageBoxService = new MessageBoxService();
    public ClassicSudokuViewModel(IMessageBoxService service)
    {
        // 没有把传入的service赋值给MessageBoxService成员
    }
}

正确的实现应该是:

public class ClassicSudokuViewModel
{
    public IMessageBoxService MessageBoxService { get; }
    public ClassicSudokuViewModel(IMessageBoxService service)
    {
        MessageBoxService = service;
    }
}

2. Mock配置写法不规范

你当前的Mock配置优先级不明确,SetReturnsDefault在MockBehavior.Strict模式下可能不生效,而且你返回的MessageBoxResult.OK和业务逻辑使用的MessageBoxButton.YesNo按钮组不匹配,应该直接返回MessageBoxResult.Yes。
修正后的测试代码:

[TestMethod]
public void Draw9x9TableWithAlreadyFilledCellsTest()
{
    Mock<IMessageBoxService> messageBoxMock = new Mock<IMessageBoxService>(MockBehavior.Strict);
    // 明确Setup业务逻辑调用的4参数Show方法,直接返回Yes
    messageBoxMock.Setup(m =>
        m.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxButton>(),
        It.IsAny<MessageBoxImage>()))
        .Returns(MessageBoxResult.Yes);
    // 可选:Setup5参数重载避免Strict模式下意外调用报错
    messageBoxMock.Setup(m =>
        m.Show(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<MessageBoxButton>(),
        It.IsAny<MessageBoxImage>(), It.IsAny<Style>()))
        .Returns(MessageBoxResult.Yes);
    
    ClassicSudokuViewModel classicSudokuViewModel = new ClassicSudokuViewModel(messageBoxMock.Object);
    SudokuBoardSize sudokuBoardSize = new SudokuBoardSize();
    sudokuBoardSize.Height = 9;
    sudokuBoardSize.Width = 9;
    sudokuBoardSize.BoxCountX = 3;
    sudokuBoardSize.BoxCountY = 3;

    BaseSudokuTableViewModel tableViewModel = classicSudokuViewModel.GetCurrentTableViewModel();
    tableViewModel.Cells[0][0] = "1";
    classicSudokuViewModel.DrawSudokuCommand.Execute(sudokuBoardSize);
    object actualBoard = classicSudokuViewModel.SudokuBoardControl;
    tableViewModel = classicSudokuViewModel.GetCurrentTableViewModel();

    Assert.AreEqual(typeof(UcClassicSudoku9x9Table), actualBoard.GetType());
    Assert.AreEqual(string.Empty, tableViewModel.Cells[0][0]);
    Assert.AreEqual(false, classicSudokuViewModel.AreDiagonalRulesApplied);
    Assert.AreEqual(string.Empty, classicSudokuViewModel.SolutionCounter);
    Assert.AreEqual(false, classicSudokuViewModel.IsSolutionCounterVisible);
    Assert.AreEqual(0, classicSudokuViewModel.Solutions.Count);
}

内容的提问来源于stack exchange,提问作者DariusDavedane

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 02:51:00