Zoeken…


Impliciet valideren van oproepvolgorde

Waar een te testen methode informatie uit één oproep gebruikt om door te geven aan volgende oproepen, is een benadering die kan worden gebruikt om ervoor te zorgen dat de methoden in de verwachte volgorde worden opgeroepen, het instellen van de verwachtingen om deze gegevensstroom weer te geven.

Gezien de te testen methode:

public void MethodToTest()
{
    var str = _utility.GetInitialValue();

    str = _utility.PrefixString(str);
    str = _utility.ReverseString(str);

    _target.DoStuff(str);
}

Verwachtingen kunnen worden ingesteld om gegevens van GetInitialValue via PrefixString en ReverseString te DoStuff aan DoStuff , waar de informatie wordt geverifieerd. Als een van de methoden buiten gebruik wordt gesteld, zijn de eindgegevens onjuist en mislukt de test.

// 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));

Callorder valideren met callbacks

Wanneer u geen strikte mocks kunt / wilt gebruiken, kunt u MockSequence niet gebruiken om de MockSequence te valideren. Een alternatieve benadering is om callbacks te gebruiken om te valideren dat de Setup verwachtingen worden opgeroepen in de verwachte volgorde. Gegeven de volgende testmethode:

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

Het kan als volgt worden getest:

// 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"));

Oproeporder valideren met MockSequence

Moq biedt ondersteuning voor het valideren van oproepvolgorde met behulp van MockSequence , maar het werkt alleen bij gebruik van strikte mocks. Dus, Gegeven de volgende testmethode:

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

Het kan als volgt worden getest:

// 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"));

In het bovenstaande voorbeeld wordt It.IsAny<string> bij het instellen van de verwachtingen. Deze hadden relevante tekenreeksen ("1111", "2222", "3333") kunnen gebruiken als er meer exacte overeenkomsten nodig waren.

De fout die wordt gerapporteerd wanneer gesprekken niet op volgorde worden geplaatst, kan een beetje misleidend zijn.

aanroep mislukt met schijngedrag Strict. Alle aanroepen op de mock moeten een overeenkomstige opstelling hebben.

Dit komt omdat elke Setup verwachting wordt behandeld alsof deze niet bestaat totdat aan de vorige verwachting in de reeks is voldaan.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow