moq
Validerar samtalsorder
Sök…
Validera samtalsordning implicit
När en metod som ska testas använder information från ett samtal för att vidarebefordra till efterföljande samtal, är en metod som kan användas för att säkerställa att metoderna anropas i förväntad ordning att ställa in förväntningarna för att återspegla detta flöde av data.
Med tanke på metoden att testa:
public void MethodToTest()
{
var str = _utility.GetInitialValue();
str = _utility.PrefixString(str);
str = _utility.ReverseString(str);
_target.DoStuff(str);
}
Förväntningar kan ställas in för att skicka data från GetInitialValue
via PrefixString
och ReverseString
till DoStuff
, där informationen verifieras. Om någon av metoderna kallas ur funktion är slutdata fel och testet misslyckas.
// Create mocks
var utilityMock = new Mock<IUtility>();
var targetMock = new Mock<ITarget>();
// Setup expectations, note that the returns value from one call matches the expected
// parameter for the next call in the sequence of calls we're interested in.
utilityMock.Setup(x => x.GetInitialValue()).Returns("string");
utilityMock.Setup(x => x.PrefixString("string")).Returns("Prefix:string");
utilityMock.Setup(x => x.ReverseString("Prefix:string")).Returns("gnirts:xiferP");
string expectedFinalInput = "gnirts:xiferP";
// Invoke the method to test
var sut = new SystemUnderTest(utilityMock.Object, targetMock.Object);
sut.MethodToTest();
// Validate that the final call was passed the expected value.
targetMock.Verify(x => x.DoStuff(expectedFinalInput));
Validera samtalsorder med återuppringningar
När du inte kan / inte vill använda strikta mockar kan du inte använda MockSequence
att validera MockSequence
. Ett alternativt tillvägagångssätt är att använda återuppringningar för att bekräfta att Setup
förväntningarna åberopas i den förväntade ordningen. Följande metod för att testa:
public void MethodToTest()
{
_utility.Operation1("1111");
_utility.Operation3("3333");
_utility.Operation2("2222");
}
Det kan testas på följande sätt:
// Create the mock (doesn't have to be in strict mode)
var utilityMock = new Mock<IUtility>();
// Create a variable to track the current call number
int callOrder = 1;
// Setup each call in the sequence to be tested. Note that the callback validates that
// that callOrder has the expected value, then increments it in preparation for the next
// call.
utilityMock.Setup(x => x.Operation1(It.IsAny<string>()))
.Callback(() => Assert.AreEqual(1, callOrder++, "Method called out of order") );
utilityMock.Setup(x => x.Operation2(It.IsAny<string>()))
.Callback(() => Assert.AreEqual(2, callOrder++, "Method called out of order") );
utilityMock.Setup(x => x.Operation3(It.IsAny<string>()))
.Callback(() => Assert.AreEqual(3, callOrder++, "Method called out of order") );
// Invoke the method to be tested
var sut = new SystemUnderTest(utilityMock.Object);
sut.MethodToTest();
// Validate any parameters that are important, note these Verifications can occur in any
// order.
utilityMock.Verify(x => x.Operation2("2222"));
utilityMock.Verify(x => x.Operation1("1111"));
utilityMock.Verify(x => x.Operation3("3333"));
Validerar samtalsorder med MockSequence
Moq tillhandahåller support för validering av MockSequence
med MockSequence
, men det fungerar bara när du använder strikta mockar. Så med tanke på följande metod för att testa:
public void MethodToTest()
{
_utility.Operation1("1111");
_utility.Operation2("2222");
_utility.Operation3("3333");
}
Det kan testas på följande sätt:
// 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"));
Ovanstående exempel använder It.IsAny<string>
när du ställer in förväntningarna. Dessa kunde ha använt relevanta strängar ("1111", "2222", "3333") om mer exakta matchningar krävdes.
Det fel som rapporteras när samtal görs i sekvens kan vara lite vilseledande.
åkallelse misslyckades med håligt beteende Strikt. Alla anropningar på håna måste ha en motsvarande inställning.
Detta beror på att varje förväntad Setup
behandlas som om den inte existerar förrän den tidigare förväntningen i sekvensen har uppfyllts.