Подтвердить что ты не робот

Как использовать Mockito с JUnit5

Как я могу использовать инъекцию с Mockito и JUnit 5?

В JUnit4 я могу просто использовать аннотацию @RunWith(MockitoJUnitRunner.class). В JUnit5 нет @RunWith Аннотации?

4b9b3361

Ответ 1

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

Вручную

Создание Mockito::mock вручную с помощью Mockito::mock работает независимо от версии JUnit (или тестовой среды в этом отношении).

Аннотации на основе

Использование @Mock -annotation и соответствующего вызова MockitoAnnotations::initMocks для создания MockitoAnnotations::initMocks работает независимо от версии JUnit (или инфраструктуры тестирования в этом отношении, но Java 9 может вмешиваться здесь, в зависимости от того, заканчивается ли тестовый код в модуле или нет).

Расширение Mockito

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.

Ответ 2

Используйте 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

    ...
}

Ответ 3

Вы должны использовать новую аннотацию @ExtendWith.

К сожалению, пока еще нет расширения. На github вы можете увидеть бета-версию для расширения. в качестве примера демонстрационного теста .

Ответ 4

Есть разные способы сделать, но более чистый способ, который также учитывает философию 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.