February 16, 2021

Example of using Moq's MockSequence in a Unit Test

This test shows how to test Properties and Methods
[Test]
[Category("AutomaticTest")]
public void Some_Test()
{
    var mockPublisher = new Mock(MockBehavior.Strict);
    var sequence = new MockSequence();
    mockPublisher.InSequence(sequence).Setup(x => x.Start());
    mockPublisher.InSequence(sequence).SetupSet(x => x.IsSynchronizing = true);
    mockPublisher.InSequence(sequence).Setup(x => x.Start());
    mockPublisher.InSequence(sequence).Setup(x => x.Complete());
    mockPublisher.InSequence(sequence).Setup(x => x.Start());
    mockPublisher.InSequence(sequence).Setup(x => x.Complete());
    mockPublisher.InSequence(sequence).Setup(x => x.Complete());
    mockPublisher.InSequence(sequence).SetupSet(x => x.IsSynchronizing = false);

    var fakeSyncObserver = new FakeSystemReportersSyncObserver();
    var fakeConnectivityObserver = new FakeEventEngineConnectivityObserver();
    Monitor Monitor = new Monitor(mockPublisher.Object, fakeSyncObserver, fakeConnectivityObserver);

    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("1", 
      SyncEnum.ReportSynchronized));    // Start(), IsSynchronizing = true
    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("2", 
      SyncEnum.ReportSynchronized));    // Start() (IsSynchronizing is already true)
    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("2", 
      SyncEnum.Completed)); // Complete() ("1" is still syncing)
    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("2", 
      SyncEnum.ReportSynchronized));    // Start() (IsSynchronizing is already true)
    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("2", 
      SyncEnum.Completed)); // Complete() ("1" is still syncing)
    fakeSyncObserver.PublishStateChanged(new SyncEventArgs("1", 
      SyncEnum.Completed)); // Complete(), IsSynchronizing = false ("1" and "2" are both complete now)

    mockPublisher.VerifyAll();
    mockPublisher.Verify(m => m.Fail(), Times.Never())
    mockPublisher.Verify(m => m.Start(), Times.Exactly(3));
}
MockSequence has a bug, make sure that there is a call of "VerifyAll()" followed by at least one call to "Verify()" otherwise the MockSequence may not actually be checked!
Here is another sample test:
[Test]
[Category("AutomaticTest")]
public void AnotherSampleTest()
{
    var mockSnmpPublisher = new Mock(MockBehavior.Strict);
    // Create the MockSequence to validate the call order
    var sequence = new MockSequence();
    // Create the expectations, notice that the Setup is called via InSequence
    mockSnmpPublisher.InSequence(sequence).Setup(
        x => x.SendTrap(
            It.Is(y => y.Equals(StatusOids.Traps.SynchronizationStarted)),
            It.Is(s => s == true)));
    mockSnmpPublisher.InSequence(sequence).
      Setup(x => x.SetVariable(It.Is(y => y.Equals(StatusOids.Variables.IsSynchronizing)), 
                      It.Is(y => y.Equals(IsSynchronizing))));
    mockSnmpPublisher.InSequence(sequence).Setup(
        x => x.SendTrap(
            It.Is(y => y.Equals(StatusOids.Traps.SynchronizationCompleted)),
            It.Is(s => s == true)));
    mockSnmpPublisher.InSequence(sequence).
           Setup(x => x.SetVariable(It.Is(y => y.Equals(StatusOids.Variables.IsSynchronizing)), 
                    It.Is(y => y.Equals(IsNotSynchronizing))));

    SyncSnmpPublisher SyncSnmpPublisher = new SyncSnmpPublisher(mockSnmpPublisher.Object);
    SyncSnmpPublisher.Start();
    SyncSnmpPublisher.IsSynchronizing = true;
    SyncSnmpPublisher.Complete();
    SyncSnmpPublisher.IsSynchronizing = false;

    mockSnmpPublisher.VerifyAll();
    mockSnmpPublisher.Verify(m =>  // REMEMBER this will ensure the MockSequence will be checked
        m.SendTrap(It.Is(y => y.Equals(StatusOids.Traps.SynchronizationCompleted)), 
            It.Is(s => s == true)), Times.Once());
}

No comments: