I want to stub a repository class to test another class (Holder class) that has a repository. The repository interface supports CRUD operations, and has many methods, but my unit test on the Holder class only needs to call two of them. The repository interface:
public interface IRepo {
public void remove(String... sarr);
public void add(String... sarr);
//Lots of other methods I don't need now
}
I want to create a repository mock that can store instances, define logic for add
and remove
only, and also provide a means of checking what is stored on it after calling add and remove.
If I do:
IRepo repoMock = mock(IRepo.class);
Then I have a dumb object that does nothing on each method. That's OK, now I just need to define behaviour for add and remove.
I could create a Set<String>
and stub only those two methods to work on the set. Then I'd instantiate a Holder that has an IRepo, inject the partially stubbed mock, and after exercising the holder, check the set to verify it contains what it should.
I've managed to partially stub a void method like remove
using the deprecated method 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());
But is deprecated, and it is not much better than creating a partial implementation for IRepo. Is there a better way?
NOTE: Java 7 answers only please, this should run in Android.
Mockito provides following methods that can be used to mock void methods. doAnswer() : We can use this to perform some operations when a mocked object method is called that is returning void. doThrow() : We can use doThrow() when we want to stub a void method that throws exception.
You can use
Mockito.doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocation) throws Throwable {
//DO SOMETHING
return null;
}
}).when(...).remove(Matchers.<String>anyVararg());
From the Javadoc:
Use doAnswer() when you want to stub a void method with generic Answer.
Stubbing voids requires different approach from Mockito.when(Object) because the compiler does not like void methods inside brackets...
Example:
doAnswer(new Answer() {
public Object answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
Mock mock = invocation.getMock();
return null;
}}).when(mock).someMethod();
See examples in javadoc for Mockito
Suppose you have
public class IFace {
public void yourMethod() {
}
}
Then to mock it you need
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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With