墨青MVVM Light的IMessenger

标签 moq mvvm-light

在尝试使用 MoqMVVM 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 时,推荐的方法是什么?

最佳答案

这是我会做的:

// 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注册/发送机制。我选择后者是因为我不需要在我的测试中做任何额外的设置来让它工作。

因此,当我需要测试我的 SUT 是否正确注册和处理消息时,我假设 IMessenger 按预期工作并且只使用一个具体实例,即:

// Create a new messenger every test
IMessenger mockMessenger = new Messenger();
// Send the message
mockMessenger.Send<IUnitsManager>(_mockUnits.Object);

关于墨青MVVM Light的IMessenger,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23797334/

相关文章:

data-binding - 绑定(bind)数据透视 header 模板

wpf - 如何将文本框添加到 Gridview 的每个标题列并使用文本框过滤该列?

c# - 将标签内容绑定(bind)到嵌套类中的值而不是 Datacontext

c# - 多个 Moq It.Is<string>() 匹配参数

c# - 最小起订量和您传递的参数

c# - 模拟一个对其参数有副作用的方法

c# - 在同一个类中模拟一个方法

c# - Mock.Verify() 失败 - 此设置不匹配?

wpf - mvvm 中的数据验证