2017-04-13 56 views
2

我想單元測試一個簡單的方法,並驗證某個事件已從該方法發佈,但發現很難設置模擬。使用Moq設置事件聚合器事件

//Class under test 
public class TreatmentRoomModel : ITreatmentRoomModel 
{ 
    public TreatmentRoomModel(IEventAggregator eventAggregator) 
    { 
      _eventAggregator = eventAggregator; 
    } 

    //Method under test 
    public void SetTreatmentInProgress(bool inProgress) 
    { 
     if (_isTreatmentInProgress == inProgress) return; 
     _isTreatmentInProgress = inProgress; 

     _eventAggregator.Publish(new TreatmentStatus(_isTreatmentInProgress), Execute.OnUIThread); 
    } 
} 

//TreatmentStatus event 
public class TreatmentStatus 
{ 
    public TreatmentStatus(bool isInProgress) 
    { 
     IsInProgress = isInProgress; 
    } 

    public bool IsInProgress { get; private set; } 
} 

我試圖測試方法SetTreatmentInProgress並驗證正確TreatmentStatus事件正由eventaggregator出版。 事件聚合器typeof(Caliburn.Micro.IEventAggregator)

下面是測試設置

[TestClass] 
public class TreatmentRoomModelTests 
{ 
    private Mock<IEventAggregator> _mockEventAggregator; 
    ITreatmentRoomModel _treatmentRoomModel; 

    private readonly TreatmentStatus _treatmentInProgressEvent = new TreatmentStatus(true); 
    private readonly TreatmentStatus _treatmentNotInProgressEvent = new TreatmentStatus(false); 

    [TestInitialize] 
    public void Initialize() 
    { 
     _mockEventAggregator = new Mock<IEventAggregator>(); 

     //I am not sure how to set the property IsInProgress of TreatmentStatus to true? It is a privately set property through constructor. 
     _mockEventAggregator.Setup(x => x.Publish(It.IsAny<TreatmentStatus>(), Execute.OnUIThread)); 

     //Or should I directly publish a true event, but then how to verify the event object without a reference to it. 
     //_mockEventAggregator.Setup(x => x.Publish(new TreatmentStatus(true), Execute.OnUIThread)); 


     _treatmentRoomModel = new TreatmentRoomModel(_mockEventAggregator.Object); 
    } 

    [TestMethod] 
    public void SetTreatmentInProgressTest() 
    { 
     _treatmentRoomModel.SetTreatmentInProgress(true); 

     //This works, but I wan't to verify that the object of TreatmentStatus event has the property IsInProgress set to true. 
     _mockEventAggregator.Verify(x=>x.Publish(It.IsAny<TreatmentStatus>(), Execute.OnUIThread),Times.Once); 


     _treatmentRoomModel.SetTreatmentInProgress(false); 

     //Won't work, as it says this is getting called Times.None. I understand this may be because of different TreatmentStatus objects, which are raised and verified. 
     _mockEventAggregator.Verify(x=>x.Publish(new TreatmentStatus(false), Execute.OnUIThread),Times.Once); 

    } 
} 

回答

2

修復使用It.Is<>

//This works, but I wan't to verify that the object of TreatmentStatus event has the property IsInProgress set to true. 
_mockEventAggregator 
.Verify(x=>x.Publish(It.Is<TreatmentStatus>(_ => _.IsInProgress == true), Execute.OnUIThread),Times.Once); 
+0

謝謝您的回答,下面是我對它的表達,但你的是光滑的:) – Marshal

1
[TestMethod] 
    public void SetTreatmentInProgressTest() 
    { 
     var inProgress = true; 

     TreatmentStatus resultStatus = null; 
     _mockEventAggregator.Setup(x => x.Publish(It.IsAny<TreatmentStatus>(), Execute.OnUIThread)) 
          .Callback<object,Action<Action>>((t,s) => resultStatus = (TreatmentStatus)t); 

     _treatmentRoomModel.SetTreatmentInProgress(inProgress); 

     Assert.IsNotNull(resultStatus); 
     Assert.IsTrue(resultStatus.IsInProgress); 
     Assert.IsTrue(_treatmentRoomModel.IsTreatmentInProgress); 

    }