テストコードでモックを書くときによく使うMockitoですが、mock()とspy()の違いについてよくわからないという方向けに図解で解説します。
目次
図解
mock()
・全てのメソッドが一旦使用不可になる。
・doReturnなどで戻り値を定義したメソッドだけ利用可能
(上図ではgetB()のみが使用可能な状態です)
spy()
・全てのメソッドはそのままで実行可能です。
・doReturnなどで戻り値を定義したメソッドだけ戻り値が上書きされます。
(上図ではgetB()のみが変更した値を返すようになります)
コード
Hoge.java(テスト対象)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
package mock; public class Hoge { public String getA() { return "A"; } public String getB() { return "B"; } public String getC() { return "C"; } } |
HogeTest.java(テストコード)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
package mock; import org.junit.jupiter.api.Test; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.is; import static org.mockito.Mockito.*; class HogeTest { @Test public void testMockCase() { Hoge hoge = mock(Hoge.class); // assertThat("A", is(hoge.getA())); doReturn("BBB").when(hoge).getB(); assertThat("BBB", is(hoge.getB())); // assertThat("C", is(hoge.getC())); } @Test public void testSpyCase() { Hoge hoge = spy(Hoge.class); assertThat("A", is(hoge.getA())); doReturn("BBB").when(hoge).getB(); assertThat("BBB", is(hoge.getB())); assertThat("C", is(hoge.getC())); } } |
testMockCase
・getA()とgetC()はnullを返すのでコメントアウトしています。
・getB()はdoReturnで指定した戻り値でテストが通ります。
testSpyCase
・getA()とgetC()はHoge.javaで定義されている元々の値を返します。
・getB()はdoReturnで指定した戻り値でテストが通ります。
使い分け
mockは特定の値を返してほしいときに使います。
spyは一部の振る舞いを変えたうえで他のクラスに食わせて、意図した振る舞いをさせるときに使います。
例えば、Hoge.javaを持つことになる別のクラスに渡すとき、getB()の戻り値がNULLであることを期待するといった場合です。
まとめ
・mockは全て使えない状態にして、指定したメソッドだけ定義通りの振る舞いにする。
・spyは全て使える状態から、指定したメソッドだけ意図した別の振る舞いをさせる。
コメント