是否可以编写一个调用 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/

10-13 01:59