Является ли это приемлемым способом проверки сообщений MVVM-Light Toolkit? - PullRequest
2 голосов
/ 26 августа 2010
    [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 значение, подобное этому:

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

Но я получил недопустимую ошибку приведения.Является ли метод OverrideDefault не для этой цели или, скорее всего, я использую его неправильно.

Или у меня был бы интерфейс для классов, которые получают сообщения и высмеивают их?Все, что я действительно хочу проверить, это то, что RelayCommand отправляет сообщение при его вызове.

Ответы [ 2 ]

3 голосов
/ 30 августа 2010

Я только начал смотреть на это сам. Я немного удивлен, что 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.

Класс TestMessenger:

    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);
    }
}
0 голосов
/ 05 декабря 2013

Другой подход, который использует инжектор конструктора, вы можете увидеть в этом ответе .Я думаю, что лучше использовать инжектор конструктора вместо статического Messenger.Default.Это более надежный подход к внедрению зависимостей, обеспечивающий естественный шов, с помощью которого можно легко заменить зависимости в модульных тестахЕсли вы попытаетесь заменить статический вызов члена, тогда вы полагаетесь на внутреннюю реализацию, которая, очевидно, может измениться.

...