Jak sprawdzić, czy ta metoda NIE została wywołana w Moq?

466

Jak sprawdzić, czy ta metoda NIE została wywołana w Moq ?

Czy ma coś takiego jak AssertWasNotCalled?

AKTUALIZACJA: Począwszy od wersji 3.0 można zastosować nową składnię:

mock.Verify(foo => foo.Execute("ping"), Times.Never());
alex
źródło

Odpowiedzi:

155

AKTUALIZACJA : Od wersji 3 sprawdź aktualizację powyższego pytania lub odpowiedź Danna poniżej.

Albo uczyń swoją próbną surową, aby nie zadziałała, jeśli wywołasz metodę, na którą nie oczekujesz

new Mock<IMoq>(MockBehavior.Strict)

Lub, jeśli chcesz, aby Twój makieta był luźny, skorzystaj z .Throws (wyjątek)

var m = new Mock<IMoq>(MockBehavior.Loose);
m.Expect(a => a.moo()).Throws(new Exception("Shouldn't be called."));
Dan Fish
źródło
9
... lub Callback (), aby ustawić flagę, którą można potwierdzić.
alex
2
Również z opcją # 2 nie można mieć VerifyAll w ogólnej metodzie Teardown - nie powie, że oczekiwanie nie zostało spełnione; kiedy test powinien idealnie przejść.
Gishu,
51
To nie jest tak naprawdę „weryfikacja nie wywołana”, ponieważ może zostać złapana w ramach metody i nadal będzie działać - zapewniając fałszywie dodatni!
Dan
4
Oczekiwanie jest teraz przestarzałe
Tomasz Sikora
5
Być może był to najlepszy możliwy sposób w 2009 r., Ale na pewno nie teraz. przepraszam
Fabio Milheiro,
537

Uruchom weryfikację po teście, który ma Times.Neverzestaw wyliczeń. na przykład

_mock.Object.DoSomething()
_mock.Verify(service => service.ShouldntBeCalled(),Times.Never());
Dan
źródło
4
Najważniejsze w tym przypadku jest to, że wywołanie Verify (akcja, Nigdy) następuje po wywołaniu mock. Myślałem, że to konfiguracja do późniejszego wywołania VerifyAll () (co nie działa)
piers7
Prosty i skuteczny. Dzięki.
Ian Grainger
45

Skradzione z: Odpowiedź Johna Fostera na pytanie „Potrzebujesz pomocy, aby lepiej zrozumieć Moq”

Jedną z rzeczy, które możesz chcieć przetestować, jest to, że metoda płatności nie jest wywoływana, gdy osoba w wieku powyżej 65 lat zostanie przekazana do tej metody

[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
źródło
10

Nie działa to w najnowszych wersjach Moq (od co najmniej 3.1), należy to określić w Verifymetodzie, jak wspomniano w odpowiedzi.

W rzeczywistości lepiej jest określić .AtMost(0)po instrukcji Returns.

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

Chociaż „rzuty” również działają, AtMost(0)jest bardziej wyraziste IMHO.

Miha
źródło
-5

Użyj .AtMostOnce ();

Po prawdziwym teście ponownie wywołaj metodę Jeśli zgłasza wyjątek, został wywołany.

Aaron Digulla
źródło
1
Czy to nie jest zbyt niejasne, aby stwierdzić, że wyjątek został zgłoszony przez kpiące środowisko?
alex
Dlaczego? Po prostu sprawdź typ wyjątku. Jeśli ktoś rzuci mój Moq, jesteś bezpieczny.
Aaron Digulla
8
Korzystanie z Verify w Timesie. Nigdy nie jest lepszym wyborem ... Zgadzam się z Alexem, że to rozwiązanie działa, ale zdecydowanie jest niejasne.
Sygnał dźwiękowy