2014-05-22 35 views
3

在試圖寫一些單元測試與起訂量,我遇到了一個問題MVVM光的信使類。問題是你怎麼能Mock<IMessenger>();並驗證收到一條消息,並處理該動作?Moqing MVVM光的IMessenger的

如果使用IMessenger,編寫測試的正確方法是什麼?我見過很多使用Messenger.Default的示例, 和TestInitialize方法中的Messenger.Reset()。我用IMessenger認爲這將有助於測試能力。

使用Moq驗證郵件是否按照我的預期發送。

[TestMethod] 
public void LoadData_SendsUpdateStatusEvents() 
    { 
     //Arrange 
     _mockMessenger.Setup(x => x.Send(It.IsAny<string>(), 
          It.IsAny<UpdateStatusEvent>())); 
     //Act 
     //Assert 
     _mockMessenger.Verify(x => x.Send(It.IsAny<string>(), 
           It.IsAny<UpdateStatusEvent>()), Times.Exactly(2)); 
    } 

但是,如果我有我的構造此註冊..

_messenger.Register<IUnitsManager>(this, OnUpdatedUnitsEvent); 

我寫一個單元測試,以檢查OnUpdatedUnitsEvent運行...

[TestMethod] 
public void OnUpdatedUnitsEvent_UpdateUserUnitValueOfAllMaterials() 
{ 
    //Arrange 
    _mockUnits.Object.SetUnitsToMetric(); 
    _mockMessenger.Object.Send(_mockUnits.Object); 

    //Act 
    var currentItem = _materialMasterVm.MaterialModels.CurrentItem as MaterialDetailViewModel; 

    //Assert 
    Assert.AreEqual(DensitySolidSymbols.KgCm3, currentItem.Density.UserUnitType); 
    Assert.AreEqual(PressureSymbols.KPa, currentItem.YieldStress); 
    Assert.AreEqual(PressureSymbols.KPa, currentItem.YoungsModulus); 
} 

什麼當使用IMessenger和Moq時,推薦使用這種方法嗎?

回答

2

這裏是我會做:

// This is a field in your test fixture 
Action<IUnitsManager> _callback; 

... 

// In your test setup, save the delegate that is registered with the message type 
mockMessenger.Setup(x => x.Register(It.IsAny<object>(), It.IsAny<Action<IUnitsManager>>())) 
      .Callback<object, Action<IUnitsManager>>((o, a) => _callback = a); 

... 

// When you want to send the message, invoke the callback 
_callback(_mockUnits.Object); 

不過,我想補充一點,使用IMessenger在測試中發送消息時,我做嘲笑它。上面的設置有點麻煩,此外,這正是Messenger混凝土無論如何。換句話說,我要麼把我的信念放在Moq的Setup/Callback機制或MVVM Light MessengerRegister/Send機制中。我選擇後者是因爲我不需要在測試中做任何額外的設置來使其工作。

所以,當我需要測試我的SUT寄存器和妥善處理的消息,我假設IMessenger按預期工作,只是用一個具體的實例,即:

// Create a new messenger every test 
IMessenger mockMessenger = new Messenger(); 
// Send the message 
mockMessenger.Send<IUnitsManager>(_mockUnits.Object);