C# 以下设置不匹配,WPF MVVM使用Moq进行单元测试
我正在用Moq在WPF中编写一个单元测试,测试用户在关闭窗口时是否单击了C# 以下设置不匹配,WPF MVVM使用Moq进行单元测试,c#,wpf,unit-testing,mvvm,moq,C#,Wpf,Unit Testing,Mvvm,Moq,我正在用Moq在WPF中编写一个单元测试,测试用户在关闭窗口时是否单击了YesNoCancel消息框上的“是”按钮。在我的CloseCommand视图中,当用户关闭窗口时,Model会给出以下消息: var result = _messageSvc.Show( "Do you want to save changes?", "Save Changes", Services.MessageBoxButton.YesNoCancel, Services.Messag
YesNoCancel
消息框上的“是”按钮。在我的CloseCommand
视图中,当用户关闭窗口时,Model会给出以下消息:
var result = _messageSvc.Show(
"Do you want to save changes?",
"Save Changes",
Services.MessageBoxButton.YesNoCancel,
Services.MessageBoxIcon.Question,
Services.MessageBoxResult.Yes);
My\u messageSvc
是自定义消息服务中的一个私有实例,用于显示消息框。以下是该服务的代码:
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();
}
[TestMethod]
public void应要求使用osaveoncloserespondentyestest()命令
{
//模拟和设置初始用户数据
var u=新用户
{
UserId=1,
UserName=“FirstName LastName”,
FavoriteColor=“蓝色”
};
mainViewModel.UserInfo=新的UserInfoDtoWrapper(u);
//断言数据尚未更改
Assert.IsFalse(mainViewModel.UserInfo.IsChanged);
//更改用户数据
mainViewModel.UserInfo.UserName=“LastName FirstName”;
//断言数据已更改
IsTrue(mainViewModel.UserInfo.IsChanged);
//执行窗口关闭
mainViewModel.CloseCommand.Execute(新对象());
//验证messagebox是否显示并单击“是”按钮
//然后,这将保存对用户实例所做的更改
var messageBox=new Mock();
messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
它是(y=>y==“保存更改”),
它是(y=>y==MessageBoxButton.YesNoCancel),
它是(y=>y==MessageBoxIcon.Question),
它是(y=>y==MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes);
messageBox.Verify();
}
错误出现在messageBox.Verify()
行上,但从我所看到的情况来看,我做的是正确的。我需要获取messagebox的返回值,以继续测试用户单击“是”按钮后发生的情况,因此我不想在内部使用带有Linq查询的Verify
,而是需要捕获结果
谢谢这行不通。测试代码中有两个问题:
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();
}
class主视图模型
{
私有只读IMessageSvc _messageSvc;
公共主视图模型(IMessageSvc svc)
{
这个。_messageSvc=svc;
}
}
[测试方法]
public void应要求使用osaveoncloserespondentyestest()命令
{
//安排
var messageBox=new Mock();
messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
它是(y=>y==“保存更改”),
它是(y=>y==MessageBoxButton.YesNoCancel),
它是(y=>y==MessageBoxIcon.Question),
它是(y=>y==MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes)
.可验证();
var mainViewModel=新的mainViewModel(messageBox.Object);
//表演
mainViewModel.CloseCommand.Execute(新对象());
//断言
messageBox.Verify();
}
当前,您正在测试调用模拟方法的代码后设置模拟方法。将您的测试重新安排为如下模式:
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)));
var messageBox=new Mock();
messageBox.Setup(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
它是(y=>y==“保存更改”),
它是(y=>y==MessageBoxButton.YesNoCancel),
它是(y=>y==MessageBoxIcon.Question),
它是(y=>y==MessageBoxResult.Yes)))
.Returns(MessageBoxResult.Yes);
mainViewModel.CloseCommand.Execute(新对象());
验证(x=>x.Show(It.Is(y=>y==“是否保存更改?”),
它是(y=>y==“保存更改”),
它是(y=>y==MessageBoxButton.YesNoCancel),
它是(y=>y==MessageBoxIcon.Question),
它是(y=>y==MessageBoxResult.Yes));
“错误出现在messageBox.Verify()行”-什么错误?ShouldAsktosaveonCloseRespondeYesTest引发异常:Moq.MockVerificationException:以下设置不匹配:IMessageSvc x=>x.Show(It.Is(y=>y==“是否保存更改?”),It.Is(y=>y==“保存更改”)…安装和验证之间的其余代码在哪里?目前没有执行任何测试。我想这就是我的问题所在。我需要验证messagebox是否显示。然后我是否应该调用“messagebox.Show”或者显示我在上面创建的messageBox对象?我以前尝试过这个,在这种情况下返回的错误是预期对模拟调用一次,但使用messageBox.Verify(x=>x.show(It.is(y=>y==“是否保存更改?”),It.is(y=>y==“保存更改”),It.Is(y=>y==MessageBoxButton.YesNoCancel),It.Is(y=>y==MessageBoxIcon.Question),It.Is(y=>y==MessageBoxResult.Yes)),Times.Once);
我将我的IMessageService注入到ViewModel中并在单元测试类中初始化,所以当我运行\u messageSvc.Verify时(x=>x.Show(It.Is(y=>y==“是否保存更改?”)、It.Is(y=>y==“保存更改”)、It.Is(y=>y==MessageBoxButton.YesNoCancel)、It.Is(y=>y==MessageBoxIcon.Question)、It.Is(y=>y==MessageBoxResult.Yes))、次)
它可以工作,但我需要设置messagebox以获取t