Biblioteca Mockito simple
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,
MockitoAnnotations.initMocks(this)
se debe llamar al método estático.
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 @RunWith
especificando MockitoJUnitRunner
qué hace 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 spring-boot-test
biblioteca.
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
desde Spring Boot?
Las pruebas unitarias están diseñadas para probar un componente de forma aislada 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 pueden ejecutarse 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
desde 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 usará en combinación @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"));
}
}
@MockBean
reemplazará el bean en el contexto de la aplicación si un bean que declara el mismo tipo ya está definido en su configuración Spring. Y la inyección se realiza en la clase donde declaras.@MockBean.
Los mecanismos DI funcionan de esta manera: registras un objeto en el contexto DI y luego puedes inyectar el objeto referenciado en el contexto Spring en una clase específica. No inyecta un objeto en el contexto DI.Al final es fácil de explicar. Si solo observa los javadocs de las anotaciones, verá los diferentes:
@Mock: (
org.mockito.Mock
)@MockBean: (
org.springframework.boot.test.mock.mockito.MockBean
)Mockito.mock ()
fuente
@MockBean
y@Mock
que uno inyectará el simulacro enSpring ApplicationContext
y el otro no?