Jak mogę używać zastrzyku z Mockito i JUnit 5?
W JUnit4 mogę po prostu użyć @RunWith(MockitoJUnitRunner.class)
Adnotacji. W JUnit5 nie ma @RunWith
adnotacji?
Jak mogę używać zastrzyku z Mockito i JUnit 5?
W JUnit4 mogę po prostu użyć @RunWith(MockitoJUnitRunner.class)
Adnotacji. W JUnit5 nie ma @RunWith
adnotacji?
Odpowiedzi:
Istnieją różne sposoby korzystania z Mockito - omówię je jeden po drugim.
Ręczne tworzenie mocków z Mockito::mock
działaniami niezależnie od wersji JUnit (lub frameworka testowego).
Korzystanie z @Mock -annotation i odpowiednie wywołanie MockitoAnnotations::initMocks
do tworzenia mocks działa niezależnie od wersji JUnit (lub ram testu dla tej sprawy, ale Java 9 mogłyby kolidować tutaj, w zależności od tego, czy kod testowy kończy się w module, czy nie).
JUnit 5 ma potężny model rozszerzeń, a Mockito niedawno opublikował jeden z identyfikatorem grupy / artefaktu org.mockito : mockito-junit-jupiter .
Możesz zastosować rozszerzenie, dodając @ExtendWith(MockitoExtension.class)
do klasy testowej i dodając adnotacje do mockowanych pól za pomocą @Mock
. Z MockitoExtension
JavaDoc:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
Dokumentacja MockitoExtension opisuje inne sposoby tworzenia instancji mocków, na przykład za pomocą iniekcji konstruktora (jeśli określasz końcowe pola w klasach testowych).
Reguły JUnit 4 i biegacze nie działają w JUnit 5, więc nie można używać MockitoRule
i Mockito runner .
@Test
musi być publiczna czy „prywatny pakiet” jest wystarczająco dobra?
Użyj Mockito's MockitoExtension
. Rozszerzenie jest zawarte w nowym artefakcie mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
Pozwala na pisanie testów tak, jak w przypadku JUnit 4:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
private Foo foo;
@InjectMocks
private Bar bar; // constructor injection
...
}
@ExtendWith(MockitoExtension.class)
jest odpowiednikiem @RunWith(MockitoJUnitRunner.class)
JUnit4
org.junit.jupiter.api.extension.Extension
Można to zrobić na różne sposoby, ale bardziej przejrzysty i zgodny z filozofią JUnit 5 polega na stworzeniu Mockito.
1) Ręczne tworzenie mocków powoduje utratę korzyści z dodatkowych kontroli Mockito, aby upewnić się, że poprawnie używasz frameworka.
2) Wywołanie MockitoAnnotations.initMocks(this)
w każdej klasie testowej jest kodem płyty kotłowej, którego możemy uniknąć.
Tworzenie tej konfiguracji w klasie abstrakcyjnej również nie jest dobrym rozwiązaniem.
Łączy wszystkie klasy testowe z klasą bazową.
Jeśli z ważnych powodów potrzebujesz nowej podstawowej klasy testowej, kończysz z 3-poziomową hierarchią klas. Proszę tego unikać.
3) Reguły testowe to specyfika JUnit 4.
Nawet o tym nie myśl.
A dokumentacja jest jasne, że:
Jeśli jednak zamierzasz opracować nowe rozszerzenie dla JUnit 5, użyj nowego modelu rozszerzenia JUnit Jupiter zamiast modelu opartego na regułach JUnit 4.
4) Test Runner naprawdę nie jest sposobem na rozszerzenie frameworka JUnit 5.
JUnit 5 uprościł piekło Runners of JUnit 4, udostępniając model rozszerzenia do pisania testów dzięki JUnit 5 Extensions.
Nawet o tym nie myśl.
Więc sprzyjaj org.junit.jupiter.api.extension.Extension
drodze.
EDYCJA: Właściwie Mockito zawiera rozszerzenie Jowisza: mockito-junit-jupiter
Następnie bardzo prosty w użyciu:
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class FooTest {
...
}
Oto dodatek do doskonałej odpowiedzi Jonathana.
Dodając jako zależność mockito-junit-jupiter
artefakt, podczas @ExtendWith(MockitoExtension.class)
wykonywania testu zostanie użyty następujący wyjątek:
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Optional; Ljava / lang / Class;) Ljava / util / Optional;
Problem polega na tym, że mockito-junit-jupiter
zależy to od dwóch niezależnych bibliotek. Na przykład dla mockito-junit-jupiter:2.19.0
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.1.0</version>
<scope>runtime</scope>
</dependency>
Problem był używany junit-jupiter-api:5.0.1
.
Ponieważ junit-jupiter-api
ruchy wciąż są częste w zakresie API, upewnij się, że polegasz na tej samej wersji, od junit-jupiter-api
której mockito-junit-jupiter
zależy.
mockito-junit-jupiter
ściągnie właściwej wersji junit-jupiter-api
?
mockito-junit-jupiter:2.19.0
. Chociaż wersje JUnit Jupiter zaczynają się od 5
. mockito-junit-jupiter powinien był określić w swoim identyfikatorze artefaktu dwie rzeczy (wersja Mockito i wersja JUnit Jupiter), aby wszystko było jaśniejsze. Na przykład, mockito-junit-jupiter-5.1:2.19.0
aby przekazać, że biblioteka jest zaprojektowana dla JUnit Jupiter 5.1.
MockitoExtension
nie wydaje się istnieć w mockito-core
wersji 3.0.0.
mockito-junit-jupiter