是否可以编写一个调用 Messenger.Default.Register 方法的单元测试,然后编写一个供 Action 使用的断言?
我想确定我的 ViewModel 在对我的命令之一调用 Execute 后是否发送了正确的消息。
我曾尝试将 Assert.AreEqual 编写为 Action,但这似乎无法正常工作。
最佳答案
听起来像是 mocking 的工作!假设您将信使界面传递给您的 View 模型(因为 dependency inversion is a Good Thing ,正是出于这个原因),如果我理解正确,您的代码应该如下所示:
public class YourViewModel
{
readonly IMessenger messenger;
public YourViewModel(IMessenger messenger)
{
this.messenger = messenger;
// setup of your delegate command to call Execute
}
void Execute(object parameter)
{
messenger.Send(new YourMessageType());
}
}
然后在您的单元测试中,您将模拟 Messenger 并验证是否调用了正确的方法,在本例中为
Send
。因此,使用流行的模拟框架 Moq :public class YourViewModelTests
{
[Test]
public void Execute_Always_SendsYourMessageType()
{
// arrange
var mockRepository = new MockRepository(MockBehavior.Loose);
var mockMessenger = mockRepository.Create<IMessenger>();
var systemUnderTest = new YourViewModel(mockMessenger.Object);
// act
systemUnderTest.YourCommand.Execute(null);
// assert
mockMessenger.Verify(p => p.Send<YourMessageType>(
It.Is(m => /* return true if it's the right message */)));
}
}
通常我会将几乎所有的“安排”阶段转移到测试设置方法中,但您应该明白这个想法。
如果您仍然想在不 mock messenger 的情况下执行此操作,并且还想使用
Messenger.Default
,则可以执行以下操作:public class YourViewModelTests
{
[Test]
public void Execute_Always_SendsYourMessageType()
{
// arrange
var systemUnderTest = new YourViewModel();
// Set the action to store the message that was sent
YourMessageType actual;
Messenger.Default.Register<YourMessageType>(this, t => actual = t);
// act
systemUnderTest.YourCommand.Execute(null);
// assert
YourMessageType expected = /* set up your expected message */;
Assert.That(actual, Is.EqualTo(expected));
}
}
关于nunit - 单元测试 MVVMLight Messenger,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/24168345/