2009-03-10 17 views
18

Czy mogę zmienić zachowanie kodu pośredniczącego w czasie wykonywania? Coś jak:Jak zmienić zachowanie skrótów?

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 
     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); // Currently fails here 
    } 

moim przykładzie kodu nadal nie w danym wierszu, fi.GetBar() nadal zwraca "A".

Czy jest jeszcze jedna sztuczka do modelowania skrótów, których zachowanie zmienia się w czasie? Wolałbym nie używać numeru fi.Stub(...).Do(...).

Ah, prawdopodobnie potrzebuję tylko wydrukowanej instrukcji, żeby ktoś uderzył mnie w głowę. Wygląda na to, że powinno to być naprawdę oczywiste, ale nie mogę go znaleźć.

+0

Wypróbuj 'fi.Stub (x => x.GetBar()) .Powrót (" A ") .Powtórz.Once();' i 'fi.Stub (x => x.GetBar()). "B"). Repeat.Once(); ' –

Odpowiedz

26

UWAGA

Zmiana zachowania odcinki to zapach kod!

Zazwyczaj oznacza to, że testy jednostkowe są zbyt skomplikowane, trudne do zrozumienia i są kruche, z łatwością łamiąc prawidłowe zmiany testowanej klasy.

Check out:

  • [Patterns xUnit Test] [1]
  • [The Art Of Unit Testing] [2]

Więc proszę: korzystać tylko z tego rozwiązania, jeśli nie możesz tego uniknąć. W moich oczach artykuł ten ogranicza się do złych rad - są jednak rzadkie sytuacje, kiedy naprawdę tego potrzebujesz.


Ach, sama to wymyśliłem. Rhino obsługuje tryb nagrywania/odtwarzania. Podczas gdy składnia AAA zawsze utrzymuje obiekty w trybie odtwarzania, możemy przełączyć się na zapis i wrócić do powtórki tylko po to, aby usunąć zachowanie stub.

Wygląda trochę hackish jednak ...

public interface IFoo { string GetBar(); } 
    [TestMethod] 
    public void TestRhino() 
    { 
     var fi = MockRepository.GenerateStub<IFoo>(); 
     fi.Stub(x => x.GetBar()).Return("A"); 
     Assert.AreEqual("A", fi.GetBar()); 

     // Switch to record to clear behaviour and then back to replay 
     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 

     fi.Stub(x => x.GetBar()).Return("B"); 
     Assert.AreEqual("B", fi.GetBar()); 
    } 

Aktualizacja:

będę używał tego w przyszłości, więc wszystko wygląda trochę ładniejszy:

internal static class MockExtension { 
    public static void ClearBehavior<T>(this T fi) 
    { 
     // Switch back to record and then to replay - that 
     // clears all behaviour and we can program new behavior. 
     // Record/Replay do not occur otherwise in our tests, that another method of 
     // using Rhino Mocks. 

     fi.BackToRecord(BackToRecordOptions.All); 
     fi.Replay(); 
    } 
} 
+0

Jeśli chcesz użyć terminologii n ative to Rhino Mocks, make it ClearExpectations –

+1

@Richard: Zachowanie dodane z '.Stub' nie stawia oczekiwań. Zastanawiasz się nad zachowaniem dodanym do '.Expect'. –

Powiązane problemy