Nunit 单元测试MVVMLight Messenger

Nunit 单元测试MVVMLight Messenger,nunit,mvvm-light,Nunit,Mvvm Light,是否可以编写一个单元测试来调用Messenger.Default.Register方法,然后编写一个断言供操作使用 我想确定在对我的一个命令调用Execute后,ViewModel是否发送了正确的消息 我已经试着将Assert.AreEqual作为Action来编写,但是这似乎不能正常工作。听起来像是一项工作!假设您将messenger界面传递给viewmodel(因为,正是出于这个原因),如果我理解正确,您的代码应该是这样的: 公共类YourViewModel { 只读IMessenger m

是否可以编写一个单元测试来调用Messenger.Default.Register方法,然后编写一个断言供操作使用

我想确定在对我的一个命令调用Execute后,ViewModel是否发送了正确的消息

我已经试着将Assert.AreEqual作为Action来编写,但是这似乎不能正常工作。

听起来像是一项工作!假设您将messenger界面传递给viewmodel(因为,正是出于这个原因),如果我理解正确,您的代码应该是这样的:

公共类YourViewModel
{
只读IMessenger messenger;
公共视图模型(IMessenger messenger)
{
this.messenger=信使;
//设置要调用Execute的委托命令
}
void Execute(对象参数)
{
Send(新的YourMessageType());
}
}
然后在单元测试中模拟messenger并验证调用了正确的方法,在本例中是
Send
。因此,使用流行的模拟框架:

公共类YourViewModelTests
{
[测试]
public void Execute\u Always\u SendsYourMessageType()
{
//安排
var mockRepository=新的mockRepository(MockBehavior.Loose);
var mockMessenger=mockRepository.Create();
var systemUnderTest=新建YourViewModel(mockMessenger.Object);
//表演
systemUnderTest.YourCommand.Execute(空);
//断言
mockMessenger.Verify(p=>p.Send(
Is(如果消息正确,则m=>/*返回true*/);
}
}
通常我会将几乎所有的“安排”阶段转移到一个测试设置方法中,但您应该明白这一点


如果您仍希望在不模仿messenger的情况下执行此操作,并且还希望使用
messenger.Default
,则可以执行以下操作:

公共类YourViewModelTests
{
[测试]
public void Execute\u Always\u SendsYourMessageType()
{
//安排
var systemUnderTest=新建YourViewModel();
//设置操作以存储已发送的邮件
您的messagetype实际值;
Messenger.Default.Register(这个,t=>actual=t);
//表演
systemUnderTest.YourCommand.Execute(空);
//断言
YourMessageType预期=/*设置预期消息*/;
断言(实际的,等于(预期的));
}
}

或者,对于每个测试,可以创建Messenger的单独副本。对于运行时,您希望使用Messenger的默认实例,但是对于单元测试,正如我所说的,为每个测试创建一个单独的副本:

        return new GalaSoft.MvvmLight.Messaging.Messenger(); // Unit Tests

        return GalaSoft.MvvmLight.Messaging.Messenger.Default; // Runtime
否则,可能会重新发明轮子,因为在需要测试ViewModel通信的更复杂的情况下,您将不得不管理Messenger订户、消息类型等。然后可能会为messenger模拟编写单元测试,确保其工作方式与原始messenger相同。在比较运行时和测试执行时,Messenger的引擎中没有什么不同之处


因此,对于测试,工厂返回相同的Messenger实例。测试方法订阅并等待,ViewModel发布;然后测试接受并退出。否则,测试超时并报告错误。我发现这种方法比模仿messenger和通过模仿验证方法是否被调用更“接近现实”。

非常感谢您的回复。有没有一种方法可以实现同样的效果,或者不使用mocking,或者使用一个与PCL一起工作的mocking库?@PaulDiston-Ah,它稍微改变了一些事情。查看我的编辑,以及模拟和PCL兼容性。