
「Mockito」でテスト対象のクラスをMock化したけど、一部は本物のメソッドを使いたい。という時に本物メソッドとMockメソッドを分けて使う方法を紹介します。
本物メソッドとMockメソッドを分けると聞くと、@Spyを思い浮かべるかと思います。
今回は、@Spyではなく、thenCallRealMethodを使って、実行するメソッドを切り分ける方法を紹介します。
@SpyとthenCallRealMethodの違いは、本記事の「解説」に記述します。
@Spyの使い方は、コチラをどうぞ。
この章でやること
thenCallRealMethodを使って、本物メソッドとMockメソッドを分けて使う方法を紹介します。
テスト対象のクラス
SampleA をテスト対象のクラスにします。
このクラスは、SampleB を使っています。
public class SampleA { private SampleB sampleB; public String createName() { int id = 1; String ret = sampleB.getName(id); return ret; } }
こちらが、SampleB のクラスです。
public class SampleB { public String getName(Integer id) { String name = null; if (id == 1) { name = "test1"; } else if (id == 2) { name = "test2"; } else { name = "other"; } return name; } }
Mockitoを使って、SampleAのテストをします。
SampleAがテスト対象のクラスです。
SampleBは、@Mockとして扱っています。
import static org.mockito.Matchers.*; import static org.mockito.Mockito.*; public class MockitoSampleTest { @Mock(name="sampleB") private SampleB sampleBMock; @InjectMocks private SampleA sampleA = new SampleA(); @Before public void setup() { MockitoAnnotations.initMocks(this); } @Test public void testVerify() { // sampleBクラスの本物のメソッドを呼び出すように設定します。 when(sampleBMock.getName((Integer)anyObject())).thenCallRealMethod(); // テスト対象のクラスを実行します。 String ret = sampleA.createName(); // 戻り値を確認する。 // sampleBクラスの本物の戻り値が返却されています。 assertEquals("test1", ret); } }
解説
SampleBは、@Mockとして扱っています。
通常であれば、SampleBの本物メソッドは呼び出されることはありません。
しかし、今回のサンプルソースでは、20行目でSampleBMockでthenCallRealMethod()を使っています。
thenCallRealMethodを使うことによって、本物のメソッドが呼び出されます。
一見すると、@Spyに非常によく似ています。
@SpyとthenCallRealMethodの違いは、
@Spyは通常、本物のメソッドを呼び出します。モックに置き換えたいメソッドのみを指定して置き換えます。
thenCallRealMethodは、thenCallRealMethodを指定することによって初めて本物のメソッドを呼び出します。
最後に
@SpyとthenCallRealMethodの違いは、非常によく似ていて使い分けが難しいように思います。
(なんで2つあるの?って感じに思えます。)
springフレームワークを使っていると、@Spyの方だと上手くテストが出来ませんでした。(インジェクトが上手くいかなかったため。)
その時は、thenCallRealMethodを使って、本物のメソッドを呼び出すことに成功しました。
個人的には、springを使う場合は、thenCallRealMethodを使う方をおススメします。
ちなみに、@Spyの使い方は、コチラをどうぞ。
それでは!
この記事はお役に立てましたか?
お役に立てたことがあればシェアしていただけると嬉しいです!