java - jupiter - Cómo usar Mockito con JUnit5
mockito junit 5 (4)
Hay diferentes formas de usar Mockito: las repasaré una por una.
A mano
Crear Mockito::mock
manualmente con Mockito::mock
funciona independientemente de la versión de JUnit (o marco de prueba para esa materia).
Basado en anotaciones
El uso de @Mock -annotation y la llamada correspondiente a MockitoAnnotations::initMocks
para crear MockitoAnnotations::initMocks
funciona independientemente de la versión de JUnit (o el marco de prueba para el caso, pero Java 9 podría interferir aquí, dependiendo de si el código de prueba termina en un módulo o no).
Extensión de mockito
JUnit 5 tiene un poderoso modelo de extensión y Mockito publicó recientemente uno bajo el ID de grupo / artefacto org.mockito : mockito-junit-jupiter .
Puede aplicar la extensión agregando @ExtendWith(MockitoExtension.class)
a la clase de prueba y anotando los campos @Mock
con @Mock
. De MockitoExtension
de MockitoExtension
:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
La documentación de Mockito aún guarda silencio sobre la extensión.
No hay reglas, no hay corredores
Las reglas y los corredores de JUnit 4 no funcionan en JUnit 5, por lo que no se pueden usar la MockitoRule
y el corredor Mockito .
¿Cómo puedo usar la inyección con Mockito y JUnit 5?
En JUnit4 solo puedo usar la @RunWith(MockitoJUnitRunner.class)
. En JUnit5 no hay @RunWith
Annotation?
Hay diferentes maneras de hacerlo, pero la forma más limpia y que también respeta la filosofía de JUnit 5 es crear una org.junit.jupiter.api.extension.Extension
para Mockito.
1) La creación de simulacros de forma manual hace que se pierda el beneficio de las comprobaciones de Mockito adicionales para garantizar que utilice correctamente el marco.
2) Llamar a MockitoAnnotations.initMocks(this)
en cada clase de prueba es un código de placa de caldera que podríamos evitar.
Y hacer esta configuración en una clase abstracta tampoco es una buena solución.
Se acopla cada clase de prueba a una clase base.
Si luego necesita una nueva clase de prueba base por buenas razones, termina con una jerarquía de clases de 3 niveles. Por favor, evita eso.
3) Las reglas de prueba son una especificidad JUnit 4.
Ni siquiera pienses en eso.
Y la documentation es clara al respecto:
Sin embargo, si pretende desarrollar una nueva extensión para JUnit 5, use el nuevo modelo de extensión de JUnit Jupiter en lugar del modelo basado en reglas de JUnit 4.
4) Test Runner no es realmente la manera de extender el framework JUnit 5.
JUnit 5 simplificó el infierno de los corredores de JUnit 4 al proporcionar un modelo de extensión para escribir pruebas gracias a las extensiones de JUnit 5.
Ni siquiera pienses en eso.
Así que favorece el modo org.junit.jupiter.api.extension.Extension
.
EDIT: En realidad, Mockito agrupa una extensión de jupiter: mockito-junit-jupiter
Entonces, muy simple de usar:
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class FooTest {
...
}
Aquí hay una adición a la excelente respuesta de Jonathan.
Al agregar como dependencia el mockito-junit-jupiter
, el uso de @ExtendWith(MockitoExtension.class)
produjo la siguiente excepción a medida que se ejecuta la prueba:
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Optional; Ljava / lang / Class;) Ljava / util / Optional;
El problema es que mockito-junit-jupiter
depende de dos bibliotecas independientes. Por ejemplo para 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>
El problema fue que usé junit-jupiter-api:5.0.1
.
Entonces, como junit-jupiter-api
mueve con frecuencia en términos de API, asegúrese de que depende de la misma versión de junit-jupiter-api
que mockito-junit-jupiter
.
Tienes que usar la nueva anotación @ExtendWith
.
Desafortunadamente todavía no hay extensión de lanzamiento. En github puedes ver una implementación beta para la extensión. como ejemplo de prueba de demostración .
Use Mockito''s MockitoExtension
. La extensión está contenida en un nuevo artefacto mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.18.0</version>
<scope>test</scope>
</dependency>
Te permite escribir pruebas como lo harías con JUnit 4:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
private Foo foo;
@InjectMocks
private Bar bar; // constructor injection
...
}