@Mock vs @MockBean vs Mockito.mock ()

Mockito.mock() vs @Mock vs @MockBean

1. Visão geral

Neste tutorial rápido, veremos três maneiras diferentes de criar objetos fictícios e como eles diferem uns dos outros - com Mockito e com o suporte de mocking Spring.

Leitura adicional:

Mockito ArgumentMatchers

Aprenda a usar o ArgumentMatcher e como ele difere do ArgumentCaptor.

Read more

Lançamento de exceção de zombaria usando o Mockito

Aprenda a configurar uma chamada de método para lançar uma exceção no Mockito.

Read more

2. Mockito.mock()

O métodoMockito.mock() nos permite criar um objeto mock de uma classe ou interface.

Em seguida, podemos usar o mock para stub retornar valores para seus métodos e verificar se eles foram chamados.

Vejamos um exemplo:

@Test
public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() {
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
    Mockito.when(localMockRepository.count()).thenReturn(111L);

    long userCount = localMockRepository.count();

    Assert.assertEquals(111L, userCount);
    Mockito.verify(localMockRepository).count();
}

Este método não precisa de mais nada antes de poder ser usado. Podemos usá-lo para criar campos de classe simulados, bem como simulações locais em um método.

3. Anotação de@Mock do Mockito

Esta anotação é uma forma abreviada para o métodoMockito.mock(). Também devemos usá-lo apenas em uma classe de teste. Ao contrário do métodomock(), precisamos habilitar as anotações Mockito para usar esta anotação.

Podemos fazer isso usandoMockitoJUnitRunner para executar o teste ou chamando o métodoMockitoAnnotations.initMocks() explicitamente.

Vejamos um exemplo usandoMockitoJUnitRunner:

@RunWith(MockitoJUnitRunner.class)
public class MockAnnotationUnitTest {

    @Mock
    UserRepository mockRepository;

    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        long userCount = mockRepository.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

Além de tornar o código mais legível,@Mock makes it easier to find the problem mock in case of a failure, as the name of the field appears in the failure message:

Wanted but not invoked:
mockRepository.count();
-> at org.example.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)
Actually, there were zero interactions with this mock.

  at org.example.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)

Além disso, quando usado em conjunto com@InjectMocks, pode reduzir significativamente a quantidade de código de configuração.

4. Anotação de@MockBean do Spring Boot

Podemos usar@MockBean para adicionar objetos fictícios ao contexto do aplicativo Spring. A simulação substituirá qualquer bean existente do mesmo tipo no contexto do aplicativo.

Se nenhum bean do mesmo tipo for definido, um novo será adicionado. Essa anotação é útil em testes de integração em que um bean específico - por exemplo, um serviço externo - precisa ser ridicularizado.

Para usar esta anotação, temos que usarSpringRunner para executar o teste:

@RunWith(SpringRunner.class)
public class MockBeanAnnotationIntegrationTest {

    @MockBean
    UserRepository mockRepository;

    @Autowired
    ApplicationContext context;

    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

Quando usamos a anotação em um campo, além de estarmos registrados no contexto do aplicativo, o mock também será injetado no campo.

Isso é evidente no código acima. Aqui, usamos o smockUserRepository injetado para stub ocount method _._ Em seguida, usamos o bean do contexto do aplicativo para verificar se é realmente o bean simulado.

5. Conclusão

Neste artigo, vimos como os três métodos para criar objetos simulados diferem e como cada um pode ser usado.

O código-fonte que acompanha este artigo está disponívelover on GitHub.