2021.06.02 仕様が変わっていたり、少し理解できたので内容を更新しました。
Mockito で Mockオブジェクトを生成する方法には、mockメソッド (mock()) と Mockアノテーション(@Mock
) の2種類があるので簡単な使い分けを考察してみました。
:1
@Mock
アノテーションを使った場合の初期化処理だった、 initMocks()
および MockitoJUnitRunner
は現行バージョン(mockito-core 3.10.0)の時点で、非推奨になっている。
:2 MockitoのHP の More info の記載内容、および少し実際に試しただけなので、不正確な内容が含まれている可能性はあります。 また、Spyについても概ね同様の考えた方で良いと思います。
mock() と @Mock の使い分け
@InjectMocks
を付けたオブジェクトのフィールドを Mockにする場合に、そのMockは @Mock
で作成する。
イメージ的には、@InjectMocks
と @Mock
は一緒に宣言して使う。
@Mock
で作成するMockオブジェクトは、利用前に初期化し、利用後は後処理(close)を行う。
Mockオブジェクトの宣言パターン
1. mock(Object.class) メソッドで生成する
Mockオブジェクトの基本の生成方法。
前述した通り、 @InjectMocks
オブジェクトのフィールド以外をMockにする場合は、こちらを使った方が、前処理と後処理を書かなくて済む。
public class RetrieveBookDetailsTest {
private BookDao bookDao = mock(BookDao.class);
@BeforeEach
void setUp() {
when(bookDao.findById(1)).thenReturn(new Book());
when(bookDao.findById(2)).thenReturn(null);
}
// 以下、Testメソッド
....
2. @Mock
アノテーションで宣言する
@Mock
で宣言したMockオブジェクトは、 openMocks()
メソッドを使って初期化を行う必要がある。
更にこのメソッドの戻り値がAutoCloseableオブジェクトとなるので、テスト終了時に close()
メソッドを実行する。
サンプルコードには、 @InjectMocks
オブジェクトを宣言するべきだったが、 openMocks()
実行時にMockオブジェクトの生成とInjectMocksオブジェクトのフィールドへのInjectionを行っていると思われる。
private AutoCloseable closeable;
@Mock
private Network network;
@BeforeEach
void setUp() {
closeable = MockitoAnnotations.openMocks(this);
}
@AfterEach
void tearDown() throws Exception {
closeable.close();
}
これを最初に書いた時よりも、Mockitoって意外とシンプルだなと感じるようにはなった。