Перейти к основному содержимому

В чем различия между Mockito.mock(), @Mock и @MockBean?

· 3 мин. чтения

Задача: Наибольшая подстрока палиндром

Для заданной строки s, верните наибольшую подстроку палиндром входящую в s. Подстрока — это непрерывная непустая последовательность символов внутри строки. Стока является палиндромом, если она читается одинаково в обоих направлениях...

ANDROMEDA 42

1. Обзор

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

2. Мокито.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.foreach.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)
Actually, there were zero interactions with this mock.

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

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

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

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

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

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

5. Вывод

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

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