Mockitoを使ってるときに、『メソッドが呼ばれたかどうか』 は verifyのtimes() を使って検証する、っていう話はよく出てくるんですが、メソッドに渡った引数(オブジェクトの中身)の検証できる方法はないのか?と思って調べてみました。
参考
https://javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/ArgumentMatchers.html
https://www.codeflow.site/ja/article/mockito-argument-matchers
Matcherの作り方
org.mockito.ArgumentMatcher を継承して、カスタムMatcherを作ります。
HashMapだったらこんな感じかな。
HashMapMatcher.java
import java.util.HashMap;
import org.mockito.ArgumentMatcher;
public class HashMapMatcher implements ArgumentMatcher<HashMap<String, String>> {
HashMap<String, String> map;
public HashMapMatcher(HashMap<String, String> map) {
this.map = map;
}
@Override
public boolean matches(HashMap<String, String> actual) {
if (this.map.keySet().size() != actual.keySet().size()) {
return false;
}
for (String key : this.map.keySet()) {
if (!actual.containsKey(key)) {
return false;
}
if (!this.map.get(key).equals(actual.get(key))) {
return false;
}
}
return true;
}
// Overrideして、mapの中身を全部出すようにしておけば、テストが失敗したときに楽。
@Override
public String toString() {
// どう出力するかはお好みで。
StringBuffer sb = new StringBuffer();
for (String key : this.map.keySet()) {
sb.append("[key:").append(key);
sb.append(", value:").append(map.get(key)).append("]");
}
return sb.toString();
}
}
使い方
org.mockito.ArgumentMatchers.argThat にカスタムMatcherを渡して使います。
HogeTest.java
// hoge.save(map); が呼ばれて、その引数が期待値と同じか検証する
verify(hoge,atLeastOnce()).save(argThat(new HashMapMatcher(map)));
終わりに
verifyじゃなくて、when ~ thenReturn のときの検証にも使えるっぽいです。
それではレッツエンジョイ テストライフ。