リポジトリ クラスをスタブして、リポジトリを持つ別のクラス (Holder クラス) をテストします。リポジトリ インターフェイスは CRUD 操作をサポートし、多くのメソッドがありますが、Holder クラスの単体テストでは、そのうちの 2 つを呼び出すだけで済みます。リポジトリ インターフェイス:
public interface IRepo {
public void remove(String... sarr);
public void add(String... sarr);
//Lots of other methods I don't need now
}
add
インスタンスを保存し、そのインスタンスのみのロジックを定義しremove
、add および remove を呼び出した後に保存されている内容を確認する手段も提供できるリポジトリ モックを作成したいと考えています。
私が行った場合:
IRepo repoMock = mock(IRepo.class);
次に、各メソッドで何もしないダム オブジェクトを作成します。これで OK です。あとは、追加と削除の動作を定義するだけです。
を作成し、その 2 つのメソッドのみをスタブ化して、セットで動作させることができますSet<String>
。次に、IRepo を持つ Holder をインスタンス化し、部分的にスタブ化されたモックを挿入し、ホルダーを実行した後、セットをチェックして、必要なものが含まれていることを確認します。
remove
非推奨のメソッドを使用するなどして、void メソッドを部分的にスタブ化することに成功しましたstubVoid
。
Set<String> mySet = new HashSet<>();
stubVoid(repoMock).toAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
Object[] args = invocation.getArguments();
String[] stringsToDelete = (String[]) args[0];
mySet.removeAll(Arrays.asList(stringsToDelete));
return null;
}
}).on().remove(Matchers.<String>anyVararg());
しかし、これは非推奨であり、IRepo の部分的な実装を作成するよりもあまり良くありません。もっと良い方法はありますか?
注意: Java 7 の回答のみお願いします。これは Android で実行されるはずです。
ベストアンサー1
使用できます
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
//DO SOMETHING
return null;
}
}).when(...).remove(Matchers.<String>anyVararg());
Javadoc より:
汎用 Answer を使用して void メソッドをスタブする場合は、doAnswer() を使用します。
void をスタブするには、コンパイラが括弧内の void メソッドを好まないため、Mockito.when(Object) とは異なるアプローチが必要です...
例:
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Mock mock = invocation.getMock();
return null;
}}).when(mock).someMethod();
MockitoのJavadocの例を参照してください