使用Moq设置事件聚合器事件

时间:2017-04-13 12:07:24

标签: c# .net unit-testing moq caliburn.micro

我正在尝试对一个简单的方法进行单元测试,并验证某个事件是否已从该方法发布,但却很难设置模拟。

//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并验证eventaggregator正在发布正确的TreatmentStatus事件。 事件聚合器为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 个答案:

答案 0 :(得分: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); 

答案 1 :(得分: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);

    }