MockitoとJUnit 5 - ExtendWithを使う

1前書き

このクイック記事では、MockitoとJUnit 5の拡張モデルを統合する方法を説明します。 JUnit 5拡張モデルの詳細については、https://www.baeldung.com/junit-5-extensions[article]をご覧ください。

最初に、 @ Mock のアノテーションが付けられたクラス属性またはメソッドパラメータのモックオブジェクトを自動的に作成する拡張機能を作成する方法を説明します。

それから、JUnit 5テストクラスで私たちのMockitoエクステンションを使います。

2 Mavenの依存関係

2.1. 必要な依存関係

JUnit 5(jupiter)と mockito の依存関係を__pom.xmlに追加しましょう。

<dependency>
    <groupId>org.junit.jupiter</groupId>
    <artifactId>junit-jupiter-engine</artifactId>
    <version>5.3.1</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-core</artifactId>
    <version>2.21.0</version>
    <scope>test</scope>
</dependency>

junit-jupiter-engine がメインのJUnit 5ライブラリであり、 junit-platform-launcher__がMavenプラグインとIDEランチャーと共に使用されることに注意してください。

2.2. Surefireプラグイン

新しいJUnitプラットフォームランチャーを使ってテストクラスを実行するようにMaven Surefireプラグインを設定しましょう。

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <dependencies>
        <dependency>
             <groupId>org.junit.platform</groupId>
             <artifactId>junit-platform-surefire-provider</artifactId>
             <version>1.0.1</version>
         </dependency>
     </dependencies>
</plugin>

2.3. JUnit 4 IDEの互換性依存関係

まだJUnit 5をサポートしていないIDEのために、私たちのテストケースがJUnit 4(ビンテージ)互換であるためには、これらの依存関係を含めましょう:

<dependency>
    <groupId>org.junit.platform</groupId>
    <artifactId>junit-platform-runner</artifactId>
    <version>1.2.0</version>
    <scope>test</scope>
</dependency>
<dependency>
     <groupId>org.junit.vintage</groupId>
     <artifactId>junit-vintage-engine</artifactId>
     <version>5.2.0</version>
     <scope>test</scope>
</dependency>

また、すべてのテストクラスに @ RunWith(JUnitPlatform.class) というアノテーションを付けることを検討する必要があります。

junit-jupiter-engine 、https://search.maven.org/classic/#searchの最新バージョン%7Cga%7C1%7Cjunit%20vintage%20engine[junit-vintage-engine]、https://search.maven.org/classic/#search%7Cga%7C1%7Cjunit-platform-launcher[ junit-platform-launcher ]、 mockito-core はMaven Centralからダウンロードできます。

3 Mockito Extension

Mockito は、ライブラリ内のJUnit5拡張機能の実装を提供します - https://search.maven.org/search?q = a:mockito-junit-jupiter[mockito-junit-jupiter]

この依存関係を__pom.xmlに含めます。

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-junit-jupiter</artifactId>
    <version>2.23.0</version>
    <scope>test</scope>
</dependency>

4テストクラスを構築する

テストクラスを作成し、それにMockitoエクステンションを添付しましょう。

@ExtendWith(MockitoExtension.class)
@RunWith(JUnitPlatform.class)
public class UserServiceUnitTest {

    UserService userService;

...//}

テストクラスのどこででも使用できるインスタンス変数のモックを注入するために、 @ Mock アノテーションを使用できます。

@Mock UserRepository userRepository;

また、モックオブジェクトをメソッドパラメータに注入することもできます。

@BeforeEach
void init(@Mock SettingRepository settingRepository) {
    userService = new DefaultUserService(userRepository, settingRepository, mailClient);

    Mockito.lenient().when(settingRepository.getUserMinAge()).thenReturn(10);

    when(settingRepository.getUserNameMinLength()).thenReturn(4);

    Mockito.lenient().when(userRepository.isUsernameAlreadyExists(any(String.class))).thenReturn(false);
}

こちらの Mockito.lenient() の使用に注意してください。初期化されたモックが実行中にテストメソッドの1つによって呼び出されなかった場合、 Mockito は__UnsupportedStubbingExceptionをスローします。モックを初期化するときにこのメソッドを使用することで、この厳密なスタブチェックを回避できます。

テストメソッドのパラメータにモックオブジェクトを挿入することもできます。

@Test
void givenValidUser__whenSaveUser__thenSucceed(@Mock MailClient mailClient) {
   //Given
    user = new User("Jerry", 12);
    when(userRepository.insert(any(User.class))).then(new Answer<User>() {
        int sequence = 1;

        @Override
        public User answer(InvocationOnMock invocation) throws Throwable {
            User user = (User) invocation.getArgument(0);
            user.setId(sequence++);
            return user;
        }
    });

    userService = new DefaultUserService(userRepository, settingRepository, mailClient);

   //When
    User insertedUser = userService.register(user);

   //Then
    verify(userRepository).insert(user);
    Assertions.assertNotNull(user.getId());
    verify(mailClient).sendUserRegistrationMail(insertedUser);
}

テストパラメータとして注入する MailClient モックは、 init メソッドで注入したのと同じインスタンスにはなりません。

5結論

Junit 5は拡張のための素晴らしいモデルを提供しました。モック作成ロジックを単純化した簡単なMockitoエクステンションをデモンストレーションしました。

この記事で使われているコードはすべてhttps://github.com/eugenp/tutorials/tree/master/testing-modules/junit-5[GitHubプロジェクト]の com.baeldung.junit5.mockito パッケージにありますいくつかの追加の単体テスト方法と共に。