Wie kann ich überprüfen, ob diese Methode in Moq NICHT aufgerufen wurde?

466

Wie überprüfe ich, ob die Methode in Moq NICHT aufgerufen wurde ?

Hat es so etwas wie AssertWasNotCalled?

UPDATE: Ab Version 3.0 kann eine neue Syntax verwendet werden:

mock.Verify(foo => foo.Execute("ping"), Times.Never());
Alex
quelle

Antworten:

155

UPDATE : Überprüfen Sie seit Version 3 das Update der obigen Frage oder die Antwort von Dann unten.

Machen Sie Ihren Mock entweder streng, damit er fehlschlägt, wenn Sie eine Methode aufrufen, für die Sie keine Erwartungen haben

new Mock<IMoq>(MockBehavior.Strict)

Oder wenn Sie möchten, dass Ihr Mock locker ist, verwenden Sie die .Throws (Ausnahme)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Dan Fish
quelle
9
... oder Callback (), um ein Flag zu setzen, das aktiviert werden kann.
alex
2
Auch mit Option 2 können Sie in einer allgemeinen Teardown-Methode kein VerifyAll haben - es wird nicht angezeigt, dass die Erwartung nicht erfüllt wurde. wenn der Test idealerweise bestehen sollte.
Gishu
51
Dies ist nicht wirklich ein "Verifizieren nicht aufgerufen", da es innerhalb der Methode abgefangen werden könnte und trotzdem funktionieren würde - ein falsches Positiv!
Dan
4
Erwartung ist jetzt veraltet
Tomasz Sikora
5
Dies war 2009 vielleicht der bestmögliche Weg, aber jetzt sicherlich nicht mehr. Entschuldigung
Fabio Milheiro
537

Führen Sie nach dem Test eine Überprüfung durch, für die eine Times.NeverAufzählung festgelegt wurde. z.B

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Dan
quelle
4
Entscheidend dabei ist, dass der Aufruf Verify (Aktion, Never) nach dem Aufruf des Mocks erfolgt. Ich dachte, es würde die Überprüfung für den späteren Aufruf von VerifyAll () einrichten (was nicht funktioniert)
piers7
Einfach und effektiv. Vielen Dank.
Ian Grainger
45

Gestohlen von: John Fosters Antwort auf die Frage "Brauchen Sie Hilfe, um Moq besser zu verstehen?"

Eines der Dinge, die Sie möglicherweise testen möchten, ist, dass die Zahlungsmethode nicht aufgerufen wird, wenn eine Person über 65 in die Methode übernommen wird

[Test]
public void Someone_over_65_does_not_pay_a_pension_contribution() {

    var mockPensionService = new Mock<IPensionService>();

    var person = new Person("test", 66);

    var calc = new PensionCalculator(mockPensionService.Object);

    calc.PayPensionContribution(person);

    mockPensionService.Verify(ps => ps.Pay(It.IsAny<decimal>()), Times.Never());
}
Chris Marisic
quelle
10

Dies funktioniert in neueren Versionen von Moq nicht (seit mindestens 3.1). Es sollte in der Verifyin der Antwort genannten Methode angegeben werden.

Eigentlich ist es besser, .AtMost(0)nach der Returns-Anweisung anzugeben .

var m = new Mock<ISomething>();
m.Expect(x => x.Forbidden()).Returns("foo").AtMost(0);

Obwohl die "Würfe" auch funktionieren, AtMost(0)ist IMHO ausdrucksvoller.

miha
quelle
-5

Verwenden Sie .AtMostOnce ();

Rufen Sie die Methode nach dem eigentlichen Test erneut auf. Wenn es eine Ausnahme auslöst, wurde es aufgerufen.

Aaron Digulla
quelle
1
Ist es nicht ein bisschen zu dunkel, um zu behaupten, dass die Ausnahme durch ein spöttisches Framework ausgelöst wurde?
alex
Warum? Überprüfen Sie einfach den Typ der Ausnahme. Wenn es einer ist, der meinen Moq geworfen hat, bist du in Sicherheit.
Aaron Digulla
8
Verwenden von Verify with Times.Never ist eine bessere Wahl ... Ich stimme Alex zu, dass diese Lösung funktioniert, aber definitiv unklar ist.
Beep Beep