2009-02-11 8 views

Antwort

133

AKTUALISIEREN: Überprüfen Sie seit Version 3 das Update auf die obige Frage oder die Antwort von Dann unten.

Entweder machen Sie Ihre Mock streng, so dass es fehlschlägt, wenn Sie eine Methode aufrufen, für die Sie nicht erwarten

new Mock<IMoq>(MockBehavior.Strict) 

Oder haben, wenn Sie Ihre Mock wollen lose sein, verwenden Sie die .Throws (Exception)

var m = new Mock<IMoq>(MockBehavior.Loose); 
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called.")); 
+6

... oder Callback(), um ein Flag zu setzen, das bestätigt werden kann. – alex

+2

Auch mit Option # 2 können Sie nicht eine VerifyAll in einer allgemeinen Teardown-Methode haben - es wird versagen zu sagen, dass die Erwartung nicht erfüllt wurde; wenn der Test idealerweise bestehen sollte. – Gishu

+38

Dies ist nicht wirklich ein "Verify nicht genannt", da es innerhalb der Methode gefangen werden könnte und trotzdem funktionieren würde - ein falsch positives Ergebnis! – Dann

-4

Verwendung .AtMostOnce();

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

+1

Ist nicht ein wenig zu obskur, um zu behaupten, dass die Ausnahme durch das Spotten von Framework ausgelöst wurde? – alex

+0

Warum? Überprüfen Sie einfach den Typ der Ausnahme. Wenn es eins ist, mein Moq, bist du in Sicherheit. –

+6

Verwenden Sie Verify mit Times.Never ist eine bessere Wahl ... Ich stimme mit Alex überein, dass diese Lösung funktioniert, aber auf jeden Fall obskur ist. –

10

Dies funktioniert nicht in neueren Versionen von Moq (mindestens 3,1 da), sollte es in den Verify Verfahren angegeben werden, wie in denerwähntantwort.

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 "wirft" funktioniert auch, AtMost(0) ist ausdruck IMHO.

+2

kann dies in Moq v3.1 nicht finden – Gishu

+0

funktioniert nicht für Methoden, die keinen Rückgabewert haben – joshperry

22

Stolen aus: John Foster's answer to the question, "Need help to understand Moq better"

Eines der Dinge, die Sie testen möchten, ist, dass die Bezahlung Methode nicht genannt bekommt, wenn eine Person im Alter von über 65 Jahren in die Methode übergeben 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()); 
} 
423

Führen Sie eine Überprüfung nach dem Test durch, der eine Times.Never Enum-Einstellung hat. z.B.

_mock.Object.DoSomething() 
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never()); 
+1

Was hier entscheidend ist, ist, dass die Verify (Aktion, nie) -Aufruf ist * nach * der Aufruf an den Schein . Ich dachte, es würde die Verifizierung für den späteren Aufruf von VerifyAll() einrichten (was * nicht * funktioniert) – piers7