MockitoとJUnit 5 - ExtendWithを使う

MockitoとJUnit 5 – ExtendWithの使用

1. 前書き

この簡単な記事では、how to integrate Mockito with the JUnit 5 extension modelを示します。 JUnit 5拡張モデルの詳細については、このarticleをご覧ください。

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

次に、JUnit 5テストクラスでMockito拡張機能を使用します。

2. Mavenの依存関係

2.1. 必要な依存関係

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


    org.junit.jupiter
    junit-jupiter-engine
    5.3.1
    test


    org.mockito
    mockito-core
    2.21.0
    test

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

2.2. Surefireプラグイン

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


    maven-surefire-plugin
    2.19.1
    
        
             org.junit.platform
             junit-platform-surefire-provider
             1.0.1
         
     

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

テストケースがJUnit4(ヴィンテージ)互換であるため、JUnit 5をまだサポートしていないIDEの場合、これらの依存関係を含めます。


    org.junit.platform
    junit-platform-runner
    1.2.0
    test


     org.junit.vintage
     junit-vintage-engine
     5.2.0
     test

また、すべてのテストクラスに@RunWith(JUnitPlatform.class)で注釈を付けることを検討する必要があります

junit-jupiter-enginejunit-vintage-enginejunit-platform-launcher、およびmockito-coreの最新バージョンは、MavenCentralからダウンロードできます。

3. Mockito拡張

Mockitoは、ライブラリ内のJUnit5拡張機能の実装を提供します–mockito-junit-jupiter。 この依存関係をpom.xml:に含めます


    org.mockito
    mockito-junit-jupiter
    2.23.0
    test

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()の使用に注意してください。 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() {
        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拡張機能を示しました。

この記事で使用されているすべてのコードは、GitHub projectcom.example.junit5.mockitoパッケージに、いくつかの追加の単体テストメソッドとともに含まれています。