リポジトリーを持つ別のクラス(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および削除します。
私が行った場合:
IRepo repoMock = mock(IRepo.class);
次に、各メソッドで何もしないダムオブジェクトがあります。これで問題ありません。追加と削除の動作を定義するだけです。
Set<String>
とスタブは、セットで機能するこれらの2つのメソッドのみです。次に、IRepoを持つホルダーをインスタンス化し、部分的にスタブされたモックを挿入し、ホルダーを実行した後、セットをチェックして、セットに必要なものが含まれていることを確認します。
廃止されたメソッドremove
を使用して、stubVoid
のようなvoidメソッドを部分的にスタブできました:
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で実行する必要があります。
使用できます
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の例を参照してください
あなたが持っていると仮定します
public class IFace {
public void yourMethod() {
}
}
それからあなたはそれをあざけるために
IFace mock = Mockito.mock(IFace.class);
Mockito.doAnswer(new Answer() {
@Override
public Object answer(InvocationOnMock invocationOnMock) throws Throwable {
//PUT YOUR CODE HERE
return null;
}
}).when(mock).yourMethod();
あなたが本当に嫌いならreturn null
Answer
の実装で、voidメソッドに委譲する独自のAnswer実装を作成できます。
public abstract class DoesSomethingAnswer implements Answer<Void> {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
doSomething(invocation);
return null;
}
protected abstract void doSomething(InvocationOnMock invocation);
}
次に、テストの行が1行少なくなります。
Set<String> mySet = new HashSet<>();
Mockito.doAnswer(new DoesSomethingAnswer() {
@Override
protected void doSomething(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
String[] stringsToDelete = (String[]) args[0];
mySet.removeAll(Arrays.asList(stringsToDelete));
}
}).when(repoMock).remove(Matchers.<String> anyVararg());
または、呼び出しからの引数だけが必要な場合:
public abstract class DoesSomethingAnswer implements Answer<Void> {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
doSomething(invocation.getArguments());
return null;
}
protected abstract void doSomething(Object[] args);
}