[java] JUnit5에서 Mockito를 사용하는 방법

Mockito 및 JUnit 5에서 주입을 어떻게 사용할 수 있습니까?

JUnit4에서는 @RunWith(MockitoJUnitRunner.class)Annotation을 사용할 수 있습니다 . JUnit5에는 @RunWith주석이 없습니까?



답변

Mockito를 사용하는 방법에는 여러 가지가 있습니다. 하나씩 살펴 보겠습니다.

수동으로

Mockito::mockJUnit 버전 (또는 해당 문제에 대한 테스트 프레임 워크)에 관계없이 수동으로 모의를 생성 합니다.

주석 기반

@Mock 주석과 모의 생성MockitoAnnotations::initMocks
위한 해당 호출을 사용하는 것은 JUnit 버전 (또는 해당 문제에 대한 테스트 프레임 워크이지만 Java 9는 테스트 코드가 모듈로 끝나는 지 여부에 따라 여기에서 간섭 할 수 있음)에 관계없이 작동합니다.

Mockito 확장

JUnit 5에는 강력한 확장 모델이 있으며 Mockito는 최근에 그룹 / 아티팩트 ID org.mockito : mockito-junit-jupiter 아래에 하나를 게시했습니다 .

@ExtendWith(MockitoExtension.class)테스트 클래스 에 추가 하고 모의 필드에 @Mock. 에서 MockitoExtension의 JavaDoc을 :

@ExtendWith(MockitoExtension.class)
public class ExampleTest {

    @Mock
    private List list;

    @Test
    public void shouldDoSomething() {
        list.add(100);
    }

}

MockitoExtension 문서 는 예를 들어 생성자 주입 (테스트 클래스에서 최종 필드를 검색하는 경우)과 같이 모의를 인스턴스화하는 다른 방법을 설명합니다.

규칙 없음, 주자 없음

JUnit 4 규칙 및 러너는 JUnit 5에서 작동하지 않으므로 MockitoRuleMockito 러너를 사용할 수 없습니다.


답변

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;
import org.mockito.InjectMocks;
import org.mockito.Mock;

@ExtendWith(MockitoExtension.class)
class MyTest {

    @Mock
    private Foo foo;

    @InjectMocks
    private Bar bar; // constructor injection

    ...
}


답변

할 수있는 방법은 여러 가지가 있지만 더 깨끗한 방법이며 JUnit 5 철학을 존중하는 org.junit.jupiter.api.extension.Extension것은 Mockito를위한 것입니다.

1) 수동으로 모의를 생성 하면 프레임 워크를 올바르게 사용하도록 추가 Mockito 검사의 이점을 잃게됩니다.

2) MockitoAnnotations.initMocks(this)모든 테스트 클래스를 호출 하는 것은 우리가 피할 수있는 보일러 플레이트 코드입니다.
그리고 추상 클래스에서이 설정을 만드는 것도 좋은 해결책이 아닙니다.
모든 테스트 클래스를 기본 클래스에 연결합니다.
정당한 이유로 새 기본 테스트 클래스가 필요한 경우 3 단계 클래스 계층 구조로 완료합니다. 그것을 피하십시오.

3) 테스트 규칙은 JUnit 4의 특이성입니다.
그렇게 생각하지 마세요.
그리고 문서 는 그것에 대해 명확합니다.

그러나 JUnit 5의 새 확장을 개발하려는 경우 JUnit 4의 규칙 기반 모델 대신 JUnit Jupiter의 새 확장 모델을 사용하십시오.

4) Test Runner는 실제로 JUnit 5 프레임 워크를 확장하는 방법이 아닙니다.
JUnit 5는 JUnit 5 Extensions 덕분에 테스트 작성을위한 확장 모델을 제공함으로써 JUnit 4의 실행자를 단순화했습니다.
그렇게 생각하지 마세요.

그러니 org.junit.jupiter.api.extension.Extension길을 선호하십시오 .


편집 : 실제로 Mockito는 목성 확장을 번들로 제공합니다. mockito-junit-jupiter

그런 다음 사용이 매우 간단합니다.

import org.mockito.junit.jupiter.MockitoExtension;

@ExtendWith(MockitoExtension.class)
public class FooTest {
     ...
}

다음은 Jonathan의 탁월한 답변에 대한 추가 사항입니다.

mockito-junit-jupiter아티팩트 를 종속성으로 추가 @ExtendWith(MockitoExtension.class)하면 테스트가 실행될 때 다음과 같은 예외가 발생했습니다.

java.lang.NoSuchMethodError : org.junit.platform.commons.support.AnnotationSupport.findAnnotation (Ljava / util / Optional; Ljava / lang / Class;) Ljava / util / Optional;

문제는 mockito-junit-jupiter두 개의 독립 라이브러리에 의존 한다는 것 입니다. 예 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-apiAPI의 측면에서 여전히 자주 이동, 당신이 동일한 버전에 따라 다릅니다 수 있도록 junit-jupiter-apimockito-junit-jupiter에 따라 달라집니다.


답변

@ExtendWith주석 을 사용해야합니다 .

불행히도 아직 확장 기능이 없습니다. 에 github에 당신은 확장을위한 베타 구현을 볼 수 있습니다. 예를 들어 데모 테스트로 .


답변