Ответы:
Простая библиотека Mockito
import org.mockito.Mock;
...
@Mock
MyService myservice;
и
import org.mockito.Mockito;
...
MyService myservice = Mockito.mock(MyService.class);
происходят из библиотеки Mockito и функционально эквивалентны.
Они позволяют имитировать класс или интерфейс, а также записывать и проверять его поведение.
Использование аннотаций короче, поэтому предпочтительнее и часто предпочтительнее.
Обратите внимание, что для включения аннотаций Mockito во время выполнения тестов необходимо вызвать
MockitoAnnotations.initMocks(this)статический метод.
Чтобы избежать побочного эффекта между тестами, рекомендуется делать это перед каждым выполнением теста:
@Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
Другой способ включить аннотации Mockito - это аннотировать тестовый класс @RunWith, указав, MockitoJUnitRunnerкоторый выполняет эту задачу, а также другие полезные вещи:
@RunWith(org.mockito.runners.MockitoJUnitRunner.class)
public MyClassTest{...}
Библиотека Spring Boot, оборачивающая библиотеку Mockito
Это действительно класс Spring Boot :
import org.springframework.boot.test.mock.mockito.MockBean;
...
@MockBean
MyService myservice;
Класс включен в spring-boot-testбиблиотеку.
Это позволяет добавлять mockito mocks в Spring ApplicationContext.
Если в контексте существует bean-компонент, совместимый с объявленным классом, он заменяет его макетом.
Если это не так, он добавляет макет в контекст как bean-компонент.
Ссылка на Javadoc:
Аннотация, которую можно использовать для добавления фиктивных элементов в Spring ApplicationContext.
...
Если любой существующий одиночный компонент того же типа, который определен в контексте, будет заменен макетом, если существующий компонент не определен, будет добавлен новый.
Когда использовать классический / простой Mockito и когда использовать @MockBeanSpring Boot?
Модульные тесты предназначены для тестирования компонента изолированно от других компонентов, и модульные тесты также имеют требование: быть максимально быстрым с точки зрения времени выполнения, поскольку эти тесты могут выполняться каждый день десятки раз на машинах разработчика.
Следовательно, вот простой совет:
Когда вы пишете тест, который не требует каких-либо зависимостей от контейнера Spring Boot, вам подойдет классический / простой Mockito: он быстрый и способствует изоляции тестируемого компонента.
Если ваш тест должен полагаться на контейнер Spring Boot, и вы также хотите добавить или имитировать один из компонентов контейнера: @MockBeanSpring Boot - это выход.
Типичное использование Spring Boot @MockBean
Поскольку мы пишем тестовый класс, аннотированный @WebMvcTest(фрагмент веб-теста).
Документация Spring Boot очень хорошо описывает это:
Часто
@WebMvcTestбудет ограничиваться одним контроллером и использоваться в сочетании с@MockBeanпредоставлением имитационных реализаций для необходимых сотрудников.
Вот пример:
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"));
}
}
@MockBeanзаменит bean-компонент в контексте приложения, если bean-компонент, объявляющий тот же тип, уже определен в вашей конфигурации Spring. И инъекция выполняется в классе, в котором вы объявляете. @MockBean.Механизмы DI работают следующим образом: вы регистрируете объект в контексте DI, а затем можете внедрить объект, на который имеется ссылка в контексте Spring, в конкретный класс. Вы не внедряете объект в контекст DI.
В конце концов, это легко объяснить. Если вы просто заглянете в javadocs аннотаций, вы увидите разницу:
@Mock: ( org.mockito.Mock)
Отметьте поле как фиктивное.
- Позволяет создавать сокращенные макеты.
- Минимизирует повторяющийся код создания макета.
- Делает тестовый класс более читабельным.
- Облегчает чтение ошибки проверки, поскольку имя поля используется для идентификации фиктивного объекта.
@MockBean: ( org.springframework.boot.test.mock.mockito.MockBean)
Аннотация, которую можно использовать для добавления фиктивных элементов в Spring ApplicationContext. Может использоваться как аннотация на уровне класса или для полей в
@Configurationклассах или тестовых классах, которые являются@RunWithSpringRunner.Моки могут быть зарегистрированы по типу или по имени компонента. Любой существующий одиночный bean-компонент того же типа, определенный в контексте, будет заменен имитацией, если существующий bean-компонент не определен, будет добавлен новый.
Когда
@MockBeanиспользуется в поле, а также зарегистрирован в контексте приложения, макет также будет введен в поле.
Mockito.mock ()
Это просто представление файла
@Mock.
@MockBeanи в @Mockтом, что один будет вводить макет в, Spring ApplicationContextа другой - нет?