2010-08-26 3 views
2
[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); 
    } 

Je vois qu'il ya une interface IMessenger et j'ai essayé de se moquer et mettre Messenger.OverrideDefault à la maquette comme ceci:Est-ce une façon acceptable de tester les messages MVVM-Light Toolkit?

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

Mais j'ai eu une erreur de casting non valide. Est-ce que la méthode OverrideDefault n'est pas dans ce but ou plus probablement je ne l'utilise pas correctement.

Ou aurais-je une interface pour les classes qui reçoivent les messages et les moque? Tout ce que je veux vraiment tester, c'est qu'un RelayCommand envoie un message quand il est appelé.

Répondre

3

Je viens de commencer à regarder moi-même. Je suis un peu surpris que Messenger.OverrideDefault ne prend pas un IMessenger en tant que paramètre. Vous devez hériter de Messenger. Je suppose que vous pourriez créer une classe qui utilise votre objet maquette en interne, puis faire une vérification.

 [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(); 
    } 

Vous pouvez avoir besoin d'un talon sur la méthode Register.

La classe 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

Une autre approche utilisant l'injection de constructeur, vous pouvez voir dans cette answer. Je pense qu'il est préférable d'utiliser l'injection de constructeur au lieu d'utiliser Messenger.Default statique. Son approche plus robuste provoque une injection de dépendances fournissant un joint naturel avec lequel vous pouvez facilement remplacer les dépendances dans les tests unitaires. Si vous essayez de substituer un appel de membre statique, alors vous comptez sur une implémentation interne qui peut évidemment changer.

Questions connexes