概要
Mockitoを使うときに、この場合はどうやったらモックをかけられるかを毎回ググっていたのですが、いい加減効率が悪いのでまとめることにしました。
本当はJMockitを使いたいのですが、黒魔術は禁止されているので、Mockitoを使います。
前提
うちはまだ2系に移行できていないので、Mockito1xが前提です。
Mockito 1.10.19
JUnit 4.11
Java 1.8.0_151
ケース
Mockitoで注意しないといけないのは、メソッドの戻り値がvoidか、そうでないかでモックのかけかたが違うということです。これを踏まえて、以下の6つに分類しました。
No | モック対象メソッドの戻り型 | モック範囲 | モック動作 |
---|---|---|---|
1 | void以外 | 全体 | 指定した戻り値を返す |
2 | void以外 | 全体 | 例外を投げる |
3 | void | 全体 | 例外を投げる |
4 | void以外 | 一部のメソッドのみ | 指定した戻り値を返す |
5 | void以外 | 一部のメソッドのみ | 例外を投げる |
6 | void | 一部のメソッドのみ | 例外を投げる |
ちなみに、privateメソッド、staticメソッド、依存オブジェクトをnewで生成しているケースは、PowerMockの範囲になりますので、また別に記事書きます。
→書きました。
PowerMock+Mockito1xでのケース別モックのかけかた
https://qiita.com/taka_22/items/27ea1fbf9c305ba83dcc
テストの書き方
No.1
/**
* publicメソッド、戻り型はvoid以外、全部モック、値を戻す
*/
@Test
public void test001() {
List mockedList = mock(List.class);
when(mockedList.get(0)).thenReturn("aaa");
assertThat((String)mockedList.get(0), is("aaa"));
assertNull(mockedList.get(1));
}
No.2
/**
* publicメソッド、戻り型はvoid以外、全部モック、例外を投げる
*/
@Test
public void test002() {
List mockedList = mock(List.class);
when(mockedList.get(0)).thenThrow(new RuntimeException("aaa"));
try {
mockedList.get(0);
fail();
} catch(RuntimeException e) {
assertThat(e.getMessage(), is("aaa"));
}
assertNull(mockedList.get(1));
}
No.3
doThrowが前に来るのがポイント。
/**
* publicメソッド、戻り型はvoid、全部モック、例外を投げる
*/
@Test
public void test003() {
List mockedList = mock(List.class);
doThrow(new RuntimeException("aaa")).when(mockedList).clear();
try {
mockedList.clear();
fail();
} catch(RuntimeException e) {
assertThat(e.getMessage(), is("aaa"));
}
assertNull(mockedList.get(0));
}
No.4
一部のみモックする場合は、mockではなくて、spyを使います。
テスト対象メソッドから呼ばれる、テスト対象でないメソッドの挙動を変えたいときなどに使います。
/**
* publicメソッド、戻り型はvoid以外、一部モック、値を戻す
*/
@Test
public void test004() {
List spiedList = spy(new ArrayList());
// リアルオブジェクトには"bbb"を追加したが
spiedList.add("bbb");
// スパイでget(0)は"aaa"を返すようにした
when(spiedList.get(0)).thenReturn("aaa");
// 結果は"aaa"が得られる
assertThat((String)spiedList.get(0), is("aaa"));
// その他のメソッドはリアルの結果が返される
assertThat(spiedList.size(), is(1));
}
No.5
/**
* publicメソッド、戻り型はvoid以外、一部モック、例外を投げる
*/
@Test
public void test005() {
List spiedList = spy(new ArrayList());
// リアルオブジェクトには"bbb"を追加したが
spiedList.add("bbb");
// スパイでget(0)はRuntimeExceptionをスローするようにした
when(spiedList.get(0)).thenThrow(new RuntimeException("aaa"));
try {
spiedList.get(0);
fail();
} catch(Exception e) {
assertThat(e.getMessage(), is("aaa"));
}
// その他のメソッドはリアルの結果が返される
assertThat(spiedList.size(), is(1));
}
No.6
/**
* publicメソッド、戻り型はvoid、一部モック、例外を投げる
*/
@Test
public void test006() {
List spiedList = spy(new ArrayList());
// リアルオブジェクトには"bbb"を追加
spiedList.add("bbb");
// clearが呼ばれたときはRuntimeExceptionを投げる
doThrow(new RuntimeException("aaa")).when(spiedList).clear();
try {
spiedList.clear();
fail();
} catch(RuntimeException e) {
assertThat(e.getMessage(), is("aaa"));
}
// その他のメソッドはリアルの結果が返される
assertThat(spiedList.size(), is(1));
assertThat((String)spiedList.get(0), is("bbb"));
}