Как я могу использовать инъекцию с Mockito и JUnit 5?
В JUnit4 я могу просто использовать аннотацию @RunWith(MockitoJUnitRunner.class)
. В JUnit5 нет @RunWith
Аннотации?
Как я могу использовать инъекцию с Mockito и JUnit 5?
В JUnit4 я могу просто использовать аннотацию @RunWith(MockitoJUnitRunner.class)
. В JUnit5 нет @RunWith
Аннотации?
Существуют разные способы использования Mockito - я расскажу о них один за другим.
Создание Mockito::mock
вручную с помощью Mockito::mock
работает независимо от версии JUnit (или тестовой среды в этом отношении).
Использование @Mock -annotation и соответствующего вызова MockitoAnnotations::initMocks
для создания MockitoAnnotations::initMocks
работает независимо от версии JUnit (или инфраструктуры тестирования в этом отношении, но Java 9 может вмешиваться здесь, в зависимости от того, заканчивается ли тестовый код в модуле или нет).
JUnit 5 имеет мощную модель расширения, и недавно Mockito опубликовал ее под идентификатором группы/артефакта org.mockito: mockito-junit-jupiter.
Вы можете применить расширение, добавив @ExtendWith(MockitoExtension.class)
к тестовому классу и аннотируя @Mock
поля с помощью @Mock
. Из MockitoExtension
JavaDoc:
@ExtendWith(MockitoExtension.class)
public class ExampleTest {
@Mock
private List list;
@Test
public void shouldDoSomething() {
list.add(100);
}
}
Документация Mockito все еще немного молчит о расширении.
Правила и бегуны JUnit 4 не работают в JUnit 5, поэтому MockitoRule
использовать MockitoRule
и бегунок Mockito.
Используйте Mockito MockitoExtension
. Расширение содержится в новом артефакте mockito-junit-jupiter
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-junit-jupiter</artifactId>
<version>2.23.4</version>
<scope>test</scope>
</dependency>
Это позволяет вам писать тесты, как если бы вы использовали JUnit 4:
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
@ExtendWith(MockitoExtension.class)
class MyTest {
@Mock
private Foo foo;
@InjectMocks
private Bar bar; // constructor injection
...
}
Вы должны использовать новую аннотацию @ExtendWith
.
К сожалению, пока еще нет расширения. На github вы можете увидеть бета-версию для расширения. в качестве примера демонстрационного теста .
Есть разные способы сделать, но более чистый способ, который также учитывает философию JUnit 5, заключается в создании org.junit.jupiter.api.extension.Extension
для Mockito.
1) Создание макетов вручную лишает вас преимуществ дополнительных проверок Mockito, чтобы обеспечить правильное использование каркаса.
2) Вызов MockitoAnnotations.initMocks(this)
в каждом тестовом классе - это код котельной пластины, которого мы могли бы избежать.
И создание этой настройки в абстрактном классе также не является хорошим решением.
Он соединяет все тестовые классы с базовым классом.
Если вам по каким-то причинам вам нужен новый базовый тестовый класс, вы заканчиваете иерархией классов уровня 3-. Пожалуйста, избегайте этого.
3) Правила тестирования - это специфика JUnit 4.
Даже не думай об этом.
И документация ясно об этом:
Однако, если вы намереваетесь разработать новое расширение для JUnit 5, используйте новую модель расширения JUnit Jupiter вместо основанной на правилах модели JUnit 4.
4) Test Runner на самом деле не является способом расширения платформы JUnit 5.
JUnit 5 упростила адские бегуны JUnit 4, предоставив модель расширения для написания тестов благодаря JUnit 5 Extensions.
Даже не думай об этом.
Так что org.junit.jupiter.api.extension.Extension
предпочтение org.junit.jupiter.api.extension.Extension
.
РЕДАКТИРОВАТЬ: На самом деле, Mockito связывает расширение mockito-junit-jupiter
: mockito-junit-jupiter
Тогда очень прост в использовании:
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
public class FooTest {
...
}
Вот дополнение к превосходному ответу Джонатана.
Добавляя в качестве зависимости mockito-junit-jupiter
, использование @ExtendWith(MockitoExtension.class)
к следующему исключению при выполнении теста:
java.lang.NoSuchMethodError: org.junit.platform.commons.support.AnnotationSupport.findAnnotation(Ljava/util/Необязательно; Ljava/lang/Class;) Ljava/util/Необязательно;
Проблема в том, что mockito-junit-jupiter
зависит от двух независимых библиотек. Например, для mockito-junit-jupiter:2.19.0
: mockito-junit-jupiter:2.19.0
:
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.1.0</version>
<scope>runtime</scope>
</dependency>
Проблема была в том, что я использовал junit-jupiter-api:5.0.1
.
Так как junit-jupiter-api
все еще часто перемещается с точки зрения API, убедитесь, что вы junit-jupiter-api
от той же версии junit-jupiter-api
, mockito-junit-jupiter
зависит mockito-junit-jupiter
.