使用 MockSequence 驗證呼叫順序

Moq 支援使用 MockSequence 驗證呼叫順序,但只有在使用嚴格模擬時才有效。因此,給出以下測試方法:

public void MethodToTest()
{
    _utility.Operation1("1111");
    _utility.Operation2("2222");
    _utility.Operation3("3333");
}

它可以測試如下:

// Create the mock, not MockBehavior.Strict tells the mock how to behave
var utilityMock = new Mock<IUtility>(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
utilityMock.InSequence(sequence).Setup(x => x.Operation1(It.IsAny<string>()));
utilityMock.InSequence(sequence).Setup(x => x.Operation2(It.IsAny<string>()));
utilityMock.InSequence(sequence).Setup(x => x.Operation3(It.IsAny<string>()));

// Run the method to be tested
var sut = new SystemUnderTest(utilityMock.Object);
sut.MethodToTest();

// Verify any parameters that are cared about to the operation being orchestrated.
// Note that the Verify calls can be in any order
utilityMock.Verify(x => x.Operation2("2222"));
utilityMock.Verify(x => x.Operation1("1111"));
utilityMock.Verify(x => x.Operation3("3333"));

以上示例在設定期望時使用 It.IsAny<string>。如果需要更精確的匹配,這些可能使用了相關的字串(111122223333)。

在不按順序進行呼叫時報告的錯誤可能有點誤導。

呼叫失敗,模擬行為嚴格。模擬上的所有呼叫都必須具有相應的設定。

這是因為,每個 Setup 期望被視為好像它不存在,直到滿足序列中的先前期望。