单元测试MVVMLight Messenger

Pau*_*ton 2 nunit mvvm-light

是否可以编写调用该方法Messenger.Default.Register单元测试,然后写一个断言由动作中使用?

我想在我的一个命令上调用Execute之后确定我的ViewModel是否正在发送正确的消息.

我已经尝试将Assert.AreEqual编写为Action但是这似乎没有正常工作.

Pat*_*irk 6

听起来像嘲笑的工作!假设你正在传递的消息界面到您的视图模型(因为依赖倒置是件好事,因为这个原因),你的代码应该是什么样,如果我理解正确的话:

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());
    }
}
Run Code Online (Sandbox Code Playgroud)

然后在您的单元测试中,您将模拟信使并验证是否调用了正确的方法,在这种情况下是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 */)));
    }
}
Run Code Online (Sandbox Code Playgroud)

通常我会把几乎所有的"排列"阶段都转移到测试设置方法中,但你应该明白这个想法.


如果你仍然喜欢这样做而不嘲笑信使并使用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));
    }
}
Run Code Online (Sandbox Code Playgroud)