1. 概要

このクイックチュートリアルでは、MockitoとSpringモックサポートを使用してモックオブジェクトを作成する3つの異なる方法を見ていきます。 また、それらが互いにどのように異なるかについても説明します。

2. Mockito.mock()

Mockito.mock()メソッドを使用すると、クラスまたはインターフェイスのモックオブジェクトを作成できます。

次に、モックを使用してそのメソッドの戻り値をスタブ化し、それらが呼び出されたかどうかを確認できます。

例を見てみましょう:

@Test
public void givenCountMethodMocked_WhenCountInvoked_ThenMockedValueReturned() {
    UserRepository localMockRepository = Mockito.mock(UserRepository.class);
    Mockito.when(localMockRepository.count()).thenReturn(111L);

    long userCount = localMockRepository.count();

    Assert.assertEquals(111L, userCount);
    Mockito.verify(localMockRepository).count();
}

このメソッドを使用する前に、他に何もする必要はありません。 これを使用して、モッククラスフィールドと、メソッド内のローカルモックを作成できます。

3. Mockitoの@Mockアノテーション

このアノテーションは、 Mockito.mock()メソッドの省略形です。 テストクラスでのみ使用する必要があることに注意してください。 mock()メソッドとは異なり、このアノテーションを使用するにはMockitoアノテーションを有効にする必要があります。

これを行うには、 MockitoJUnitRunner を使用してテストを実行するか、 MockitoAnnotations.initMocks()メソッドを明示的に呼び出します。

MockitoJUnitRunnerを使用した例を見てみましょう。

@RunWith(MockitoJUnitRunner.class)
public class MockAnnotationUnitTest {
    
    @Mock
    UserRepository mockRepository;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        long userCount = mockRepository.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

コードを読みやすくするだけでなく、 @Mockを使用すると、障害メッセージにフィールドの名前が表示されるため、障害が発生した場合に問題のモックを簡単に見つけることができます。

Wanted but not invoked:
mockRepository.count();
-> at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)
Actually, there were zero interactions with this mock.

  at org.baeldung.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)

さらに、 @InjectMocks と組み合わせて使用すると、セットアップコードの量を大幅に減らすことができます。

4. Spring Bootの@MockBeanアノテーション

@MockBean を使用して、Springアプリケーションコンテキストにモックオブジェクトを追加できます。 モックは、アプリケーションコンテキスト内の同じタイプの既存のBeanを置き換えます。

同じタイプのBeanが定義されていない場合は、新しいBeanが追加されます。 このアノテーションは、外部サービスなどの特定のBeanをモックする必要がある統合テストで役立ちます。

このアノテーションを使用するには、SpringRunnerを使用してテストを実行する必要があります。

@RunWith(SpringRunner.class)
public class MockBeanAnnotationIntegrationTest {
    
    @MockBean
    UserRepository mockRepository;
    
    @Autowired
    ApplicationContext context;
    
    @Test
    public void givenCountMethodMocked_WhenCountInvoked_ThenMockValueReturned() {
        Mockito.when(mockRepository.count()).thenReturn(123L);

        UserRepository userRepoFromContext = context.getBean(UserRepository.class);
        long userCount = userRepoFromContext.count();

        Assert.assertEquals(123L, userCount);
        Mockito.verify(mockRepository).count();
    }
}

フィールドで注釈を使用すると、モックがフィールドに挿入され、アプリケーションコンテキストに登録されます。

これは上記のコードで明らかです。 ここでは、注入された UserRepository モックを使用してカウントメソッドをスタブ化しました。次に、アプリケーションコンテキストからのBeanを使用して、それが実際にモックされたBeanであることを確認しました。

5. 結論

この記事では、モックオブジェクトを作成するための3つの方法の違いと、それぞれの使用方法について説明しました。

この記事に付属するソースコードは、GitHubから入手できます。