Diferencia entre @Mock, @MockBean y Mockito.mock ()

Al crear pruebas y burlarse de las dependencias, ¿cuál es la diferencia entre estos tres enfoques?

  1. @MockBean:

    @MockBean MyService myservice; 
  2. @Burlarse de:

     @Mock MyService myservice; 
  3. Mockito.mock ()

     MyService myservice = Mockito.mock(MyService.class); 

Biblioteca de 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 tanto 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 los efectos secundarios entre las pruebas, se recomienda hacerlo antes de cada ejecución de la 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 MockitoJUnitRunner que 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 de 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 simulaciones de Mockito en 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 frijol.

Referencia de Javadoc:

Anotación que se puede usar para agregar simulaciones a Spring ApplicationContext.

Si cualquier único bean existente del mismo tipo definido en el contexto será reemplazado por el simulacro, si no se define un bean existente, se agregará uno nuevo.


¿Cuándo usar Mockito clásico / simple y cuándo usar @MockBean desde Spring Boot?

Las pruebas unitarias están diseñadas para probar un componente aislado de otros componentes y las pruebas unitarias también requieren: 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 una docena de veces en las máquinas reveladoras.

En consecuencia, aquí hay una guía simple:

Mientras escribe una prueba que no necesita ninguna dependencia del contenedor Spring Boot, el clásico / simple Mockito es la manera de seguir: es rápido y favorece el aislamiento del componente probado.
Si su prueba necesita confiar en el contenedor Spring Boot y también desea agregar o simular uno de los beans contenedores: @MockBean de Spring Boot es el camino.


Uso típico de Spring Boot @MockBean

A medida que 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 único controlador y se usará en combinación con @MockBean para proporcionar implementaciones simuladas para los colaboradores necesarios.

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")); } } 

Al final es fácil de explicar. Si solo observas los javadocs de las anotaciones, verás los diferentes:

@Mock: ( org.mockito.Mock )

 Mark a field as a mock. - Allows shorthand mock creation. - Minimizes repetitive mock creation code. - Makes the test class more readable. - Makes the verification error easier to read because the field name is used to identify the mock. 

@MockBean: ( org.springframework.boot.test.mock.mockito.MockBean )

 Annotation that can be used to add mocks to a Spring ApplicationContext. Can be used as a class level annotation or on fields in either @Configuration classes, or test classes that are @RunWith the SpringRunner. Mocks can be registered by type or by bean name. Any existing single bean of the same type defined in the context will be replaced by the mock, if no existing bean is defined a new one will be added. When @MockBean is used on a field, as well as being registered in the application context, the mock will also be injected into the field. 

Mockito.mock ()

 Its just the representation of a @Mock.