使用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
相关产品推荐
相关产品推荐

