Mockito.mock () против @Mock против @MockBean

Mockito.mock() vs @Mock vs @MockBean

1. обзор

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

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

Mockito ArgumentMatchers

Узнайте, как использовать ArgumentMatcher и чем он отличается от ArgumentCaptor.

Read more

Насмешливое Бросание Исключений с использованием Мокито

Научитесь настраивать вызов метода для выдачи исключения в Mockito.

Read more

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's@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 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)

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

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

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

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

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

@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 mock, чтобы заглушить методcount _._ Затем мы использовали компонент из контекста приложения, чтобы убедиться, что это действительно фиктивный компонент.

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

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

Исходный код, прилагаемый к этой статье, доступенover on GitHub.