Mam prywatną metodę w mojej klasie testowej, która konstruuje często używany Bar
obiekt. Bar
Konstruktor wywołuje someMethod()
metodę w moim wyśmiewali obiektu:
private @Mock Foo mockedObject; // My mocked object
...
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
}
W niektórych moich metodach testowych, które chcę sprawdzić, someMethod
został również wywołany przez ten konkretny test. Coś w stylu:
@Test
public void someTest() {
Bar bar = getBar();
// do some things
verify(mockedObject).someMethod(); // <--- will fail
}
To się nie udaje, ponieważ wyśmiewany obiekt someMethod
wywołał się dwukrotnie. Nie chcę, aby moje metody testowe przejmowały się skutkami ubocznymi mojej getBar()
metody, więc czy uzasadnione byłoby zresetowanie mojego próbnego obiektu na końcu getBar()
?
private Bar getBar() {
Bar result = new Bar(mockedObject); // this calls mockedObject.someMethod()
reset(mockedObject); // <-- is this OK?
}
Pytam, ponieważ dokumentacja sugeruje, że resetowanie fałszywych obiektów ogólnie wskazuje na złe testy. Jednak wydaje mi się to w porządku.
Alternatywny
Wydaje się, że alternatywnym wyborem jest wołanie:
verify(mockedObject, times(2)).someMethod();
co moim zdaniem zmusza każdy test do poznania oczekiwań getBar()
, bez żadnego zysku.
Mockito.clearInvocations(T... mocks)
Wyodrębniono z dokumentów mockito .
Radzę, abyś starał się unikać używania
reset()
. Moim zdaniem, jeśli zadzwonisz dwukrotnie do SomeMethod, powinno to zostać przetestowane (być może jest to dostęp do bazy danych lub inny długi proces, o który chcesz dbać).Jeśli naprawdę Cię to nie obchodzi, możesz użyć:
Zauważ, że to ostatnie może spowodować fałszywy wynik, jeśli wywołasz metodę getMar z metody getBar, a nie później (jest to niewłaściwe zachowanie, ale test się nie powiedzie).
źródło
verify
mojej prywatnej metody (co zgadzam się, prawdopodobnie tam nie należy). Cieszę się z twoich komentarzy na temat tego, czy twoja odpowiedź zmieni się.Absolutnie nie. Jak to często bywa, trudność w napisaniu czystego testu jest główną czerwoną flagą na temat projektu kodu produkcyjnego. W takim przypadku najlepszym rozwiązaniem jest refaktoryzacja kodu, aby konstruktor Bar nie wywoływał żadnych metod.
Konstruktory powinny konstruować, a nie logikę. Weź wartość zwracaną metody i przekaż ją jako parametr konstruktora.
staje się:
Jeśli spowodowałoby to powielenie tej logiki w wielu miejscach, zastanów się nad stworzeniem metody fabrycznej, którą można przetestować niezależnie od obiektu Bar:
Jeśli refaktoryzacja jest zbyt trudna, dobrym pomysłem jest użycie reset (). Wyjaśnijmy jednak - oznacza to, że kod jest źle zaprojektowany.
źródło