这是测试MVVM-Light工具包消息的可接受方式吗?

问题描述:

[TestMethod()] 
    public void ShowSetup_SendsMessage_WhenShowSetupCommandCalled() 
    { 

     //Arrange 
     Messenger.Reset(); 
     MainViewModel target = new MainViewModel(); 
     bool wasCalled = false; 
     Messenger.Default.Register<NotificationMessage>(this,"Settings",(msg) => wasCalled = true); 

     //Act 
     target.ShowSetupCommand.Execute(null); 

     //Assert 
     Assert.IsTrue(wasCalled); 
    } 

我看到有一个IMessenger的界面,我试图嘲弄并设置Messenger.OverrideDefault像这样的模拟:这是测试MVVM-Light工具包消息的可接受方式吗?

var mock = new Mock<IMessenger>();  
Messenger.OverrideDefault((Messenger)mock.Object); 

但我得到了一个无效的转换错误。 OverrideDefault方法不是为了这个目的,或者更可能是我错误地使用它。

或者我会为接收消息和模拟这些类的接口吗?我真正想测试的是RelayCommand在被调用时发送消息。

我刚开始自己​​看看这个。 Messenger.OverrideDefault没有将IMessenger作为参数,我有点惊讶。你必须继承Messenger。

我想你可以创建一个内部使用你的模拟对象,然后做一个验证的类。

 [Test] 
    public void ShowSetup_SendsMessage_WhenShowSetupCommandCalled() { 
     Messenger.Reset(); 
     MaintenanceViewModel target = new MainViewModel(); 
     IMessenger mockMessenger = MockRepository.GenerateMock<IMessenger>(); 
     mockMessenger.Expect(m => m.Send("Settings")); 
     TestMessenger testMessenger = new TestMessenger(mockMessenger); 
     Messenger.OverrideDefault(testMessenger); 
     bool wasCalled = false; 
     Messenger.Default.Register<NotificationMessage>(this, "Settings", (msg) => wasCalled = true); 
     target.ShowSetupCommand.Execute(null); 

     mockMessenger.VerifyAllExpectations(); 
    } 

您可能需要也可能不需要Register方法的存根。

public class TestMessenger : Messenger { 
    private IMessenger _mockMessenger; 
    public TestMessenger(IMessenger mock) { 
     _mockMessenger = mock; 
    } 
    public override void Register<TMessage>(object recipient, bool receiveDerivedMessagesToo, Action<TMessage> action) { 
     _mockMessenger.Register<TMessage>(recipient, receiveDerivedMessagesToo, action); 
    } 

    public override void Register<TMessage>(object recipient, Action<TMessage> action) { 
     _mockMessenger.Register<TMessage>(recipient, action); 
    } 

    public override void Send<TMessage, TTarget>(TMessage message) { 
     _mockMessenger.Send<TMessage, TTarget>(message); 
    } 

    public override void Send<TMessage>(TMessage message) { 
     _mockMessenger.Send<TMessage>(message); 
    } 

    public override void Unregister<TMessage>(object recipient, Action<TMessage> action) { 
     _mockMessenger.Unregister<TMessage>(recipient, action); 
    } 

    public override void Unregister<TMessage>(object recipient) { 
     _mockMessenger.Unregister<TMessage>(recipient); 
    } 

    public override void Unregister(object recipient) { 
     _mockMessenger.Unregister(recipient); 
    } 
} 

另一种方法是使用构造器注入可以在这个answer看到:

的TestMessenger类。我认为最好使用构造函数注入来代替使用静态Messenger.Default。这是更强大的方法导致依赖注入提供自然缝,你可以很容易地在单元测试中替代依赖关系。如果您尝试替换静态成员调用,那么您依赖于显然可以更改的内部实现。