在尝试用 Moq 和 MVVM Light 的信使类写一些单元测试时,我遇到了一个问题。问题是您如何Mock<IMessenger>();
并验证是否收到了邮件并处理了操作?
如果使用IMessenger
,编写测试的正确方法是什么?我使用Messenger.Default看过很多例子,
在Messenger.Reset()
方法中使用TestInitialize
。我使用IMessenger
认为它有助于测试能力。
使用Moq验证邮件是否按预期发送。
[TestMethod]
public void LoadData_SendsUpdateStatusEvents()
{
//Arrange
_mockMessenger.Setup(x => x.Send(It.IsAny<string>(),
It.IsAny<UpdateStatusEvent>()));
//Act
//Assert
_mockMessenger.Verify(x => x.Send(It.IsAny<string>(),
It.IsAny<UpdateStatusEvent>()), Times.Exactly(2));
}
但是,如果我在构造函数中进行了此注册..
_messenger.Register<IUnitsManager>(this, OnUpdatedUnitsEvent);
我编写了一个单元测试来检查OnUpdatedUnitsEvent是否运行...
[TestMethod]
public void OnUpdatedUnitsEvent_UpdateUserUnitValueOfAllMaterials()
{
//Arrange
_mockUnits.Object.SetUnitsToMetric();
_mockMessenger.Object.Send(_mockUnits.Object);
//Act
var currentItem = _materialMasterVm.MaterialModels.CurrentItem as MaterialDetailViewModel;
//Assert
Assert.AreEqual(DensitySolidSymbols.KgCm3, currentItem.Density.UserUnitType);
Assert.AreEqual(PressureSymbols.KPa, currentItem.YieldStress);
Assert.AreEqual(PressureSymbols.KPa, currentItem.YoungsModulus);
}
使用IMessenger和Moq时,建议使用什么方法?
答案 0 :(得分:2)
这就是我要做的事情:
// This is a field in your test fixture
Action<IUnitsManager> _callback;
...
// In your test setup, save the delegate that is registered with the message type
mockMessenger.Setup(x => x.Register(It.IsAny<object>(), It.IsAny<Action<IUnitsManager>>()))
.Callback<object, Action<IUnitsManager>>((o, a) => _callback = a);
...
// When you want to send the message, invoke the callback
_callback(_mockUnits.Object);
但是,我想补充一点,当使用IMessenger
在测试中发送消息时,我会不嘲笑它。上面的设置有点麻烦,而且,这正是Messenger
混凝土无论如何都要做的事情。换句话说,我要么信任Moq的Setup
/ Callback
机制,要么信任MVVM Light Messenger
&#39; s {{ 1}} / Register
机制。我选择后者是因为我不需要在测试中进行任何额外的设置以使其正常工作。
因此,当我需要测试我的SUT注册并正确处理消息时,我假设Send
按预期工作,只使用一个具体的实例,即:
IMessenger