Come utilizzare Mockito con JUnit5


103

Come posso usare l'iniezione con Mockito e JUnit 5?

In JUnit4 posso semplicemente usare @RunWith(MockitoJUnitRunner.class)Annotation. In JUnit5 non c'è @RunWithannotazione?

Risposte:


145

Esistono diversi modi per utilizzare Mockito: li esaminerò uno per uno.

Manualmente

La creazione manuale di mock con Mockito::mockfunziona indipendentemente dalla versione di JUnit (o dal framework di test per quella materia).

Basato su annotazioni

L'utilizzo dell'annotazione @Mock e la chiamata corrispondente a MockitoAnnotations::initMocks per creare mock funziona indipendentemente dalla versione di JUnit (o dal framework di test, ma Java 9 potrebbe interferire qui, a seconda che il codice di test finisca in un modulo o meno).

Estensione Mockito

JUnit 5 ha un potente modello di estensione e Mockito ne ha recentemente pubblicato uno con l'ID gruppo / artefatto org.mockito : mockito-junit-jupiter .

Puoi applicare l'estensione aggiungendo @ExtendWith(MockitoExtension.class)alla classe di test e annotando i campi derisi con @Mock. Dal MockitoExtensionJavaDoc di:

@ExtendWith(MockitoExtension.class)
public class ExampleTest {

    @Mock
    private List list;

    @Test
    public void shouldDoSomething() {
        list.add(100);
    }

}

La documentazione di MockitoExtension descrive altri modi per istanziare i mock, ad esempio con l'iniezione nel costruttore (se si rpefer i campi finali nelle classi di test).

Niente regole, niente corridori

Le regole ei corridori di JUnit 4 non funzionano in JUnit 5, quindi non è possibile utilizzare MockitoRuleil corridore e il Mockito .


6
Ora esiste un'estensione ufficiale Mockito Junit5 che è l'equivalente di MockitoJUnitRunner -> mockito-junit-jupiter
dan carter

Quando è stata rilasciata l'estensione ufficiale per Mockito, ha scritto un post sul blog con maggiori dettagli su come configurarlo e utilizzarlo: solidsoft.wordpress.com/2018/03/27/…
Marcin Zajączkowski

Il metodo annotato con @Testdeve essere pubblico o "pacchetto privato" è abbastanza buono?
Geek

Quando si eseguono test con Jupiter (spesso indicato come "JUnit 5"), i metodi di test devono essere visibili solo dal pacchetto.
Nicolai

57

Usa Mockito's MockitoExtension. L'estensione è contenuta in un nuovo artefatto mockito-junit-jupiter:

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.23.4</version>
    <scope>test</scope>
</dependency>

Ti consente di scrivere test come faresti con 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

    ...
}

6
@ExtendWith(MockitoExtension.class)è l'equivalente di @RunWith(MockitoJUnitRunner.class)JUnit4
Sergey Nemchinov

9

Ci sono diversi modi per farlo, ma il modo più pulito e che rispetta anche la filosofia di JUnit 5 è creare un org.junit.jupiter.api.extension.Extensionper Mockito.

1) La creazione manuale di mock fa perdere il vantaggio di ulteriori controlli Mockito per assicurarsi di utilizzare correttamente il framework.

2) La chiamata MockitoAnnotations.initMocks(this)in ogni classe di prova è un codice di targa che potremmo evitare.
E anche fare questa configurazione in una classe astratta non è una buona soluzione.
Associa ogni classe di test a una classe base.
Se poi hai bisogno di una nuova classe di test di base per buoni motivi, finisci con una gerarchia di classi a 3 livelli. Si prega di evitarlo.

3) Test Rules è una specificità di JUnit 4.
Non pensarci nemmeno.
E la documentazione è chiara su questo:

Tuttavia, se intendi sviluppare una nuova estensione per JUnit 5, utilizza il nuovo modello di estensione di JUnit Jupiter invece del modello basato su regole di JUnit 4.

4) Test Runner non è davvero il modo per estendere il framework JUnit 5.
JUnit 5 ha semplificato l'inferno dei Runners di JUnit 4 fornendo un modello di estensione per la scrittura di test grazie a JUnit 5 Extensions.
Non pensarci nemmeno.

Quindi favorisci la org.junit.jupiter.api.extension.Extensionvia.


EDIT: In realtà, Mockito racchiude un'estensione di Giove: mockito-junit-jupiter

Quindi, molto semplice da usare:

import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class FooTest {
     ...    
}

Ecco un'aggiunta all'eccellente risposta di Jonathan.

Aggiungendo come dipendenza l' mockito-junit-jupiterartefatto, l'uso di ha @ExtendWith(MockitoExtension.class)prodotto la seguente eccezione durante l'esecuzione del test:

java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Optional; Ljava / lang / Class;) Ljava / util / Optional;

Il problema è che mockito-junit-jupiterdipende da due librerie indipendenti. Ad esempio per 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>

Il problema è stato che ho usato junit-jupiter-api:5.0.1.

Quindi, poiché si junit-jupiter-apimuove ancora spesso in termini di API, assicurati di dipendere dalla stessa versione da junit-jupiter-apicui mockito-junit-jupiterdipende.


perché non mockito-junit-jupiterestrae la versione corretta di junit-jupiter-api?
haelix

@haelix Perché la strategia di versione utilizzata per questa dipendenza si basa sulla libreria Mockito. Guarda la versione qui mockito-junit-jupiter:2.19.0. Mentre le versioni di JUnit Jupiter iniziano con 5. mockito-junit-jupiter avrebbe dovuto specificare nel suo identificatore di artefatto le due cose (versione Mockito e versione JUnit Jupiter) per rendere le cose più chiare. Ad esempio mockito-junit-jupiter-5.1:2.19.0per comunicare che la libreria è progettata per JUnit Jupiter 5.1.
davidxxx

MockitoExtensionnon sembra esistere nella mockito-coreversione 3.0.0.
Thunderforge

1
@Thunderforge Questo è definito inmockito-junit-jupiter
davidxxx

3

Devi usare la nuova @ExtendWithannotazione.

Purtroppo non ci sono ancora estensioni ancora rilasciate. Su GitHub puoi vedere un'implementazione beta per l'estensione. come prova demo di esempio .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.