我正在使用 Moq 在 WPF 中编写单元测试,以测试用户是否点击了"是"关闭窗口时YesNoCancel
MessageBox上的按钮。在我的CloseCommand
我的ViewModel中,当用户关闭窗口时会显示以下消息:
var result = _messageSvc.Show(
"Do you want to save changes?",
"Save Changes",
Services.MessageBoxButton.YesNoCancel,
Services.MessageBoxIcon.Question,
Services.MessageBoxResult.Yes);
我的_messageSvc
是自定义Messaging服务中的私有实例,用于显示消息框。以下是该服务的代码:
public interface IMessageSvc
{
void Show(string message);
MessageBoxResult Show(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon, MessageBoxResult defaultResult = 0);
}
public class MessageSvc : IMessageSvc
{
public void Show(string message)
{
MessageBox.Show(message);
}
public MessageBoxResult Show(string message, string caption, MessageBoxButton buttons, MessageBoxIcon icon, MessageBoxResult defaultResult)
{
return (MessageBoxResult)MessageBox.Show(message, caption, (System.Windows.MessageBoxButton)buttons, (System.Windows.MessageBoxImage)icon, (System.Windows.MessageBoxResult)defaultResult);
}
}
注意:MessageBoxButton
,MessageBoxIcon
和MessageBoxResult
是我在同一文件中创建的枚举,以模仿.NET提供的开箱即用功能。为了便于阅读,我没有在这里展示它们
我的单元测试是:
[TestMethod]
public void ShouldAskToSaveOnCloseRespondYesTest()
{
// Mock and setup initial user data
var u= new User
{
UserId = 1,
UserName = "FirstName LastName",
FavoriteColor = "Blue"
};
mainViewModel.UserInfo= new UserInfoDtoWrapper(u);
// assert the data has not changed yet
Assert.IsFalse(mainViewModel.UserInfo.IsChanged);
// change the user data
mainViewModel.UserInfo.UserName= "LastName FirstName";
// assert the data has changed
Assert.IsTrue(mainViewModel.UserInfo.IsChanged);
// execute window closing
mainViewModel.CloseCommand.Execute(new object());
// verify messagebox shows and the 'Yes' button is clicked
// this will then save the changes made to the user instance
var messageBox = new Mock<IMessageSvc>();
messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
It.Is<string>(y => y == "Save Changes"),
It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes);
messageBox.Verify();
}
错误出现在messageBox.Verify()
行,但从我可以看到的我正确地做到了。我需要获取消息框的返回值以继续测试用户单击&#34;是&#34;按钮,所以我不想在内部使用带有Linq查询的Verify
,而是需要捕获结果。
由于
答案 0 :(得分:2)
这不起作用。您的测试代码中有2个问题:
首先触发CloseCommand
(假设调用IMessageSvc.Show
方法),然后只为该服务设置模拟。
您为服务设置了新的模拟但不使用它。
纠正这些错误:
以下是一个例子:
class MainViewModel
{
private readonly IMessageSvc _messageSvc;
public MainViewModel(IMessageSvc svc)
{
this._messageSvc = svc;
}
}
[TestMethod]
public void ShouldAskToSaveOnCloseRespondYesTest()
{
// Arrange
var messageBox = new Mock<IMessageSvc>();
messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
It.Is<string>(y => y == "Save Changes"),
It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes)
.Verifiable();
var mainViewModel = new MainViewModel(messageBox.Object);
// Act
mainViewModel.CloseCommand.Execute(new object());
// Assert
messageBox.Verify();
}
答案 1 :(得分:0)
目前,您正在测试调用它的代码之后设置模拟方法。将测试重新安排到AAA (Arrange, Act, Assert)模式中,如下所示:
var messageBox = new Mock<IMessageSvc>();
messageBox.Setup(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
It.Is<string>(y => y == "Save Changes"),
It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes);
mainViewModel.CloseCommand.Execute(new object());
messageBox.Verify(x => x.Show(It.Is<string>(y => y == "Do you want to save changes?"),
It.Is<string>(y => y == "Save Changes"),
It.Is<MessageBoxButton>(y => y == MessageBoxButton.YesNoCancel),
It.Is<MessageBoxIcon>(y => y == MessageBoxIcon.Question),
It.Is<MessageBoxResult>(y => y == MessageBoxResult.Yes)));