java - mockito spring
Diferencia entre @Mock, @MockBean y Mockito.mock() (2)
Al crear pruebas y burlarse de dependencias, ¿cuál es la diferencia entre estos tres enfoques?
-
@MockBean:
@MockBean MyService myservice;
-
@Burlarse de:
@Mock MyService myservice;
-
Mockito.mock ()
MyService myservice = Mockito.mock(MyService.class);
Al final es fácil de explicar. Si solo observa los javadocs de las anotaciones, verá los diferentes:
@Mock: (
org.mockito.Mock
)
Marcar un campo como un simulacro.
- Permite la creación de simulacros de taquigrafía.
- Minimiza el código repetitivo de creación simulada.
- Hace que la clase de prueba sea más legible.
- Hace que el error de verificación sea más fácil de leer porque el nombre del campo se usa para identificar el simulacro.
@MockBean: (
org.springframework.boot.test.mock.mockito.MockBean
)
Anotación que se puede usar para agregar simulacros a un Spring ApplicationContext. Se puede usar como una anotación de nivel de clase o en campos en las clases
@Configuration
o en las clases de prueba que son@RunWith
SpringRunner.Los simulacros se pueden registrar por tipo o por nombre de bean. Cualquier bean único existente del mismo tipo definido en el contexto será reemplazado por el simulacro, si no se define ningún bean existente, se agregará uno nuevo.
Cuando
@MockBean
se usa en un campo, además de registrarse en el contexto de la aplicación, el simulacro también se inyectará en el campo.
Mockito.mock ()
Es solo la representación de un
@Mock
.
Biblioteca Mockito llana
import org.mockito.Mock;
...
@Mock
MyService myservice;
y
import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);
provienen de la biblioteca Mockito y son funcionalmente equivalentes.
Permiten burlarse de una clase o una interfaz y registrar y verificar comportamientos en ella.
La forma de usar la anotación es más corta, por lo que es preferible y, a menudo, preferida.
Tenga en cuenta que para habilitar las anotaciones de Mockito durante las ejecuciones de prueba, debe llamarse al método estático
MockitoAnnotations.initMocks(this)
.
Para evitar efectos secundarios entre las pruebas, se recomienda hacerlo antes de cada ejecución de prueba:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
Otra forma de habilitar las anotaciones de Mockito es anotar la clase de prueba con
@RunWith
especificando el
MockitoJUnitRunner
que realiza esta tarea y también otras cosas útiles:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Biblioteca Spring Boot que envuelve la biblioteca Mockito
Esta es de hecho una clase Spring Boot :
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
La clase está incluida en la biblioteca
spring-boot-test
.
Permite agregar simulacros de Mockito en un Spring
ApplicationContext
.
Si existe un bean compatible con la clase declarada en el contexto, lo
reemplaza
por el simulacro.
Si no es el caso,
agrega
el simulacro en el contexto como un bean.
Referencia de Javadoc:
Anotación que se puede usar para agregar simulacros a un Spring ApplicationContext.
...
Si cualquier bean único existente del mismo tipo definido en el contexto será reemplazado por el simulacro, si no se define ningún bean existente, se agregará uno nuevo.
¿Cuándo se usa Mockito clásico / simple y cuando se usa
@MockBean
de Spring Boot?
Las pruebas unitarias están diseñadas para probar un componente aisladamente de otros componentes y las pruebas unitarias también tienen un requisito: ser lo más rápido posible en términos de tiempo de ejecución ya que estas pruebas se pueden ejecutar cada día docenas de veces en las máquinas desarrolladoras.
En consecuencia, aquí hay una guía simple:
A medida que escribe una prueba que no necesita dependencias del contenedor Spring Boot, el clásico / simple Mockito es el camino a seguir: es rápido y favorece el aislamiento del componente probado.
Si su prueba necesita basarse en el contenedor Spring Boot
y
también desea agregar o burlarse de uno de los beans del contenedor:
@MockBean
de Spring Boot es el camino.
Uso típico de Spring Boot
@MockBean
Mientras escribimos una clase de prueba anotada con
@WebMvcTest
(segmento de prueba web).
La documentación de Spring Boot lo resume muy bien:
A menudo,
@WebMvcTest
se limitará a un solo controlador y se utilizará en combinación con@MockBean
para proporcionar implementaciones simuladas para los colaboradores requeridos.
Aquí hay un ejemplo :
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@RunWith(SpringRunner.class)
@WebMvcTest(FooController.class)
public class FooControllerTest {
@Autowired
private MockMvc mvc;
@MockBean
private FooService fooServiceMock;
@Test
public void testExample() throws Exception {
Foo mockedFoo = new Foo("one", "two");
Mockito.when(fooServiceMock.get(1))
.thenReturn(mockedFoo);
mvc.perform(get("foos/1")
.accept(MediaType.TEXT_PLAIN))
.andExpect(status().isOk())
.andExpect(content().string("one two"));
}
}