2009-05-20 9 views
11

Czy ktoś może mi powiedzieć, dlaczego poniższy test nie zawodzi?Rhino Mocks: Repeat.Once() nie działa?

[Test] 
public void uhh_what() { 
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>(); 
    a.Expect(x => x.Notify()).Repeat.Once(); 
    a.Notify(); 
    a.Notify(); 
    a.VerifyAllExpectations(); 
} 

Naprawdę potrzebujemy drugą parę oczu do potwierdzenia nie jestem szalony ... teraz obawiam się, że wszystkie moje testy są nierzetelne.

Odpowiedz

23

Istnieje już thread on the RhinoMocks group.

GenerateMock tworzy dynamiczną próbę. Dynamiczne makiety pozwalają na połączenia, które nie są określone (= oczekiwano). Jeśli tak się stanie, po prostu zwróci wartość null (lub wartość domyślną zwracanego typu).

Uwaga: Powtórz to specyfikacja zachowania (np. Skrót), a nie oczekiwania, nawet jeśli jest określona w oczekiwaniu.

Jeśli chcesz uniknąć konieczności więcej niż określoną liczbę połączeń, można napisać:

[Test] 
public void uhh_what() 
{ 
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>(); 
    a.Expect(x => x.Notify()).Repeat.Once(); 
    a.Stub(x => x.Notify()).Throw(new InvalidOperationException("gotcha")); 
    a.Notify(); 

    // this fails 
    a.Notify(); 

    a.VerifyAllExpectations(); 
} 

Albo

[Test] 
public void uhh_what() 
{ 
    var a = MockRepository.GenerateMock<IPrebuiltNotifier>(); 
    a.Notify(); 
    a.Notify(); 

    // this fails 
    a.AssertWasCalled(
     x => x.Notify(), 
     o => o.Repeat.Once()); 
} 
+1

oh! Nie wiedziałem, że AssertWasCalled miał drugi argument, w którym można było zrobić więcej specyfikacji, to wszystko zmieni! –

+1

Jest to ten sam problem z PartialMock, jeśli kiedykolwiek go przekroczysz. – Dennis

+1

Pierwsze rozwiązanie (w którym wyrzucisz wyjątek) _will_ sprawi, że test się nie powiedzie, jeśli 'Powiadom' zostanie wywołany więcej niż raz. Jeśli jednak zostanie wywołany tylko raz (przynajmniej to jest to, co zakładam, że testowany kod powinien zrobić), test nie przejdzie tak, jak powinien, ponieważ oczekuje on dwukrotnego wywołania "Powiadomienia", które nigdy nie nadchodzi. Skonfiguruj 'a.Expect (x => x.Notify()) .Powtórz.Once()', po którym następuje 'a.Stub (x => x.Notify().) Zgłasza (...)' aby zrobić praca. – geoffmazeroff

7

Podczas korzystania GenerateMock (lub z dynamicznych Mocks w ogólności) zawsze wstawić mentalnie:

a.Expect (x => x.Notify()). Powtórzyć. * [AtLeast] * Raz();

Powiązane problemy