Mockitoを利用したテスト時に、モック化したオブジェクトのメソッドを実行する時などに使用するマッチャーについてのメモになります。
事前準備
前回の記事で使用したコードを少し修正して以下のようなサンプルがあるとします。
- SendDataクラス:何かのデータ送信を実行し、その結果(文字列)を返す
- SendDataServiceクラス:SendDataクラスを実行し、その文字数を返す
// SendData.java public class SendData { public String send(String str1, String str2) { String result = str1 + str2; return result; } }
// SendDataService.java public class SendDataService { @Autowired private SendData sendData; public int execute() { String result = sendData.send("foo", "bar"); return result.length(); } }
テストコードの作成
以下が作成したテストコードとなります。
// SendDataServiceTest.java import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; public class SendDataServiceTest { @InjectMocks private SendDataService service = new SendDataService(); @Mock private SendData sendData; @Before public void setup() { MockitoAnnotations.initMocks(this); } @After public void tearDown() throws Exception { } @Test public void executeTest() { when(sendData.send(anyString(), eq("bar"))).thenReturn("hoge"); // int result; try { // 実行 int result = service.execute(); MatcherAssert.assertThat(result, CoreMatchers.is("hoge".length())); } catch (Exception exception) { exception.printStackTrace(); fail(); } } }
モック化したオブジェクトであるsendDataのsendメソッドに渡す引数(String, String)の箇所がポイントとなり、第1引数のanyString()はどのStringクラスのオブジェクトでもマッチさせます。
第2引数のeq(...)では、同じインスタンスであるかをマッチさせます。
ここで第2引数を"bar"というような文字列を渡してしまうと以下のようなエラーが発生します。
Invalid use of argument matchers\! 2 matchers expected, 1 recorded: This exception may occur if matchers are combined with raw values: //incorrect: someMethod\(anyObject\(\), "raw String"\); When using matchers, all arguments have to be provided by matchers\. For example: //correct: someMethod\(anyObject\(\), eq\("String by matcher"\)\);
つまりマッチャーを使用する場合は、すべての引数をマッチャーで渡してあげなければならないようです。
この他にもなんでもマッチさせるany()や、intだけのanyInt()など様々なマッチャーが提供されています。