Рубрики
Без рубрики

Mockito.mock() vs @Mock vs @MockBean

Узнайте различия между различными типами насмешек с помощью Mockito.

Автор оригинала: baeldung.

1. Обзор

В этом кратком руководстве мы рассмотрим три различных способа создания макетных объектов и то, как они отличаются друг от друга – с помощью Mockito и с помощью поддержки Spring mocking.

Дальнейшее чтение:

Mockito Argumentmatcher

Насмешливый бросок исключений с помощью Mockito

2. Mockito.mock()

Метод Mockito.mock() позволяет нам создать макет объекта класса или интерфейса.

Затем мы можем использовать макет, чтобы заглушить возвращаемые значения для его методов и проверить, были ли они вызваны.

Давайте рассмотрим пример:

@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();
}

Этот метод не нуждается в каких-либо других действиях, прежде чем его можно будет использовать. Мы можем использовать его для создания полей фиктивного класса, а также локальных насмешек в методе.

3. Mockito @Mock Аннотация

Эта аннотация является сокращением для метода Mockito.mock () . Кроме того, мы должны использовать его только в тестовом классе. В отличие от метода mock () , нам нужно включить аннотации Mockito, чтобы использовать эту аннотацию.

Мы можем сделать это либо с помощью MockitoJUnitRunner для запуска теста, либо с помощью явного вызова метода MockitoAnnotations.initMocks () .

Давайте рассмотрим пример с использованием MockitoJUnitRunner :

@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();
    }
}

Помимо того, что код становится более читабельным, @Mock облегчает поиск проблемного макета в случае сбоя, так как имя поля появляется в сообщении об ошибке:

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

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

Кроме того, при использовании в сочетании с @InjectMocks он может значительно уменьшить объем кода настройки.

4. Аннотация @MockBean Spring Boot

Мы можем использовать @MockBean для добавления макетных объектов в контекст приложения Spring. Макет заменит любой существующий компонент того же типа в контексте приложения.

Если ни один компонент того же типа не определен, будет добавлен новый. Эта аннотация полезна в интеграционных тестах, где необходимо издеваться над конкретным компонентом – например, над внешней службой.

Чтобы использовать эту аннотацию, мы должны использовать Spring Runner для запуска теста:

@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();
    }
}

Когда мы используем аннотацию в поле, а также регистрируемся в контексте приложения, макет также будет введен в поле.

Это видно из приведенного выше кода. Здесь мы использовали введенный UserRepository макет, чтобы заглушить count метод . Затем мы использовали боб из контекста приложения, чтобы убедиться, что это действительно издевательский боб.

5. Заключение

В этой статье мы рассмотрели, как различаются три метода создания макетных объектов и как каждый из них можно использовать.

Исходный код, сопровождающий эту статью, доступен на GitHub .