Mockito.mock() vs @Mock vs @MockBean
1. 概要
このクイックチュートリアルでは、モックオブジェクトを作成する3つの異なる方法と、それらが互いにどのように異なるかを見ていきます。MockitoとSpringモックのサポートです。
参考文献:
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 makes it easier to find the problem mock in case of a failure, as the name of the field appears in the failure message:
Wanted but not invoked:
mockRepository.count();
-> at org.example.MockAnnotationTest.testMockAnnotation(MockAnnotationTest.java:22)
Actually, there were zero interactions with this mock.
at org.example.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 mockを使用してcount method _._をスタブ化しました。次に、アプリケーションコンテキストからのBeanを使用して、それが実際にモックされたBeanであることを確認しました。
5. 結論
この記事では、モックオブジェクトを作成する3つの方法がどのように異なり、それぞれをどのように使用できるかを説明しました。
この記事に付属するソースコードは、over on GitHubで入手できます。