Jak używać Mockito z JUnit5


109

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 @RunWithadnotacji?

Odpowiedzi:


153

Istnieją różne sposoby korzystania z Mockito - omówię je jeden po drugim.

Ręcznie

Ręczne tworzenie mocków z Mockito::mockdziałaniami niezależnie od wersji JUnit (lub frameworka testowego).

Oparte na adnotacjach

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).

Rozszerzenie Mockito

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 MockitoExtensionJavaDoc:

@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).

Bez zasad, bez biegaczy

Reguły JUnit 4 i biegacze nie działają w JUnit 5, więc nie można używać MockitoRulei Mockito runner .


6
Istnieje teraz oficjalne rozszerzenie Mockito Junit5, które jest odpowiednikiem MockitoJUnitRunner -> mockito-junit-jupiter
dan carter

Kiedy oficjalne rozszerzenie do Mockito zostało wydane, napisał post na blogu ze szczegółami, jak go skonfigurować i używać: solidsoft.wordpress.com/2018/03/27/…
Marcin Zajączkowski

Czy metoda z adnotacją @Testmusi być publiczna czy „prywatny pakiet” jest wystarczająco dobra?
Geek

Podczas uruchamiania testów z Jowiszem (często nazywanym „JUnit 5”), metody testowe muszą być widoczne tylko w pakiecie.
Nicolai Parlog

61

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

    ...
}

7
@ExtendWith(MockitoExtension.class)jest odpowiednikiem @RunWith(MockitoJUnitRunner.class)JUnit4
Sergey Nemchinov

Czy mogę wykonać wiele wywołań metody z różnymi wartościami zwracanymi w metodzie obiektu Mock przy użyciu MockitoExtension.class w JUnit5
Raj Hassani

@RajHassani Tak, możesz zobaczyć tutaj .
Jonathan

10

org.junit.jupiter.api.extension.ExtensionMoż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.Extensiondrodze.


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-jupiterartefakt, 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-jupiterzależ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-apiruchy wciąż są częste w zakresie API, upewnij się, że polegasz na tej samej wersji, od junit-jupiter-apiktórej mockito-junit-jupiterzależy.


dlaczego nie mockito-junit-jupiterściągnie właściwej wersji junit-jupiter-api?
haelix

@haelix Ponieważ strategia wersji używana dla tej zależności opiera się na bibliotece Mockito. Spójrz na wersję tutaj 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.0aby przekazać, że biblioteka jest zaprojektowana dla JUnit Jupiter 5.1.
davidxxx

MockitoExtensionnie wydaje się istnieć w mockito-corewersji 3.0.0.
Thunderforge

1
@Thunderforge To jest zdefiniowane wmockito-junit-jupiter
davidxxx

3

Musisz użyć nowej @ExtendWithadnotacji.

Niestety nie ma jeszcze żadnego rozszerzenia. Na github możesz zobaczyć wersję beta rozszerzenia. jako przykład test demo .

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.