Napisałem fabrykę do produkcji java.sql.Connection
przedmiotów:
public class MySQLDatabaseConnectionFactory implements DatabaseConnectionFactory {
@Override public Connection getConnection() {
try {
return DriverManager.getConnection(...);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
Chciałbym zweryfikować przekazane parametry DriverManager.getConnection
, ale nie wiem, jak wyśmiewać metodę statyczną. Używam JUnit 4 i Mockito do moich przypadków testowych. Czy istnieje dobry sposób na wyszydzenie / zweryfikowanie tego konkretnego przypadku użycia?
java
unit-testing
mocking
mockito
Naftuli Kay
źródło
źródło
static
, ale przez przypadek . Ograniczenie to (wraz z brakiem wsparcia dla kpiącychfinal
klas / metod lubnew
obiektów -ed) jest naturalną (ale niezamierzoną) konsekwencją podejścia zastosowanego do implementacji kpienia, w którym dynamicznie tworzone są nowe klasy, które implementują / rozszerzają kpiący typ; inne kpiące biblioteki używają innych podejść, które omijają te ograniczenia. Stało się to również w świecie .NET.Odpowiedzi:
Użyj PowerMockito na Mockito.
Przykładowy kod:
Więcej informacji:
źródło
@RunWith(PowerMockRunner.class)
i poniżej@PowerMockRunnerDelegate(JUnit4.class)
.Typową strategią unikania metod statycznych, których nie można w żaden sposób uniknąć, jest tworzenie zawijanych obiektów i używanie zamiast nich obiektów opakowujących.
Obiekty opakowania stają się fasadami prawdziwych klas statycznych, a ty ich nie testujesz.
Obiekt opakowania może być podobny
Wreszcie, twoja testowana klasa może korzystać z tego obiektu singleton, na przykład mając domyślnego konstruktora do użytku w prawdziwym życiu:
A tutaj masz klasę, którą można łatwo przetestować, ponieważ nie używasz bezpośrednio klasy za pomocą metod statycznych.
Jeśli używasz CDI i możesz skorzystać z adnotacji @Inject, jest to jeszcze łatwiejsze. Po prostu stwórz fasolę Wrapper @ApplicationScoped, wstrzyknij tę rzecz jako współpracownika (nie potrzebujesz nawet bałaganiarskich konstruktorów do testowania) i kontynuuj kpiny.
źródło
Miałem podobny problem. Przyjęta odpowiedź nie działała dla mnie, dopóki nie dokonałem zmiany:
@PrepareForTest(TheClassThatContainsStaticMethod.class)
zgodnie z dokumentacją PowerMock dla mockStatic .I nie muszę używać
BDDMockito
.Moja klasa:
Moja klasa testowa:
źródło
Jak wspomniano wcześniej, nie można kpić z metod statycznych za pomocą mockito.
Jeśli zmiana środowiska testowania nie jest opcją, możesz wykonać następujące czynności:
Utwórz interfejs dla DriverManager, wyśmiewaj ten interfejs, wstrzyknij go przez pewien rodzaj wstrzyknięcia zależności i sprawdź na tym wzorcu.
źródło
Uwaga: Kiedy wywołujesz metodę statyczną w jednostce statycznej, musisz zmienić klasę w @PrepareForTest.
Na przykład:
Aby uzyskać powyższy kod, jeśli chcesz wyśmiewać klasę MessageDigest, użyj
Chociaż jeśli masz coś takiego:
następnie musisz przygotować klasę, w której znajduje się ten kod.
A następnie wykpisz metodę:
źródło
Możesz to zrobić z odrobiną refaktoryzacji:
Następnie możesz rozszerzyć klasę,
MySQLDatabaseConnectionFactory
aby zwracała próbne połączenie, robiła twierdzenia na temat parametrów itp.Klasa rozszerzona może znajdować się w przypadku testowym, jeśli znajduje się w tym samym pakiecie (do czego zachęcam)
źródło
Aby kpić z metody statycznej, powinieneś użyć Powermock: https://github.com/powermock/powermock/wiki/MockStatic . Mockito nie zapewnia tej funkcjonalności.
Możesz przeczytać miły artykuł o mockito: http://refcardz.dzone.com/refcardz/mockito
źródło
Mockito nie może przechwytywać metod statycznych, ale od Mockito 2.14.0 można go symulować, tworząc instancje metod statycznych.
Przykład (wyciąg z ich testów ):
Ich celem nie jest bezpośrednie wspieranie statycznego kpina, ale poprawa jego publicznych interfejsów API, aby inne biblioteki, takie jak Powermockito , nie musiały polegać na wewnętrznych interfejsach API ani bezpośrednio musiały duplikować kodu Mockito. ( źródło )
źródło
Napisałem również kombinację Mockito i AspectJ: https://github.com/iirekm/varia/tree/develop/ajmock
Twój przykład to:
źródło
Ponieważ ta metoda jest statyczna, ma już wszystko, czego potrzebujesz, aby ją wykorzystać, więc pokonuje cel drwiny. Szydzenie z metod statycznych jest uważane za złą praktykę.
Jeśli spróbujesz to zrobić, oznacza to, że jest coś nie tak ze sposobem, w jaki chcesz przeprowadzić testowanie.
Oczywiście możesz użyć PowerMockito lub dowolnego innego frameworka, który może to zrobić, ale spróbuj przemyśleć swoje podejście.
Na przykład: spróbuj wyśmiewać / dostarczyć obiekty, które zamiast tego zużywa ta metoda statyczna.
źródło
Użyj frameworka JMockit . To zadziałało dla mnie. Nie musisz pisać instrukcji dla kpiącej metody DBConenction.getConnection (). Wystarczy poniższy kod.
@Mock poniżej to pakiet mockit.Mock
źródło