I have a builder:
class Builder{
private String name;
private String address;
public Builder setName(String name){
this.name = name;
You can use RETURN_DEEP_STUBS to mock a chaining API.
If you know the exact order your builder will be called, here's an example of how you would use it:
Builder b = Mockito.mock(Builder.class, RETURNS_DEEP_STUBS);
when(b.setName("a name").setAddress("an address")).thenReturn(b);
assert b.setName("a name").setAddress("an address") == b; // this passes
Unfortunately this won't give you a generic way of mocking "all the various builder methods" so that they always return this, see the other answer is you need that.
As of Mockito 2.0 (beta), there is a new default answer for RETURNS_SELF that behaves almost identically to David Wallace's answer. Example from the Mockito docs:
@Test
public void use_full_builder_with_terminating_method() {
HttpBuilder builder = mock(HttpBuilder.class, RETURNS_SELF);
HttpRequesterWithHeaders requester = new HttpRequesterWithHeaders(builder);
String response = "StatusCode: 200";
when(builder.request()).thenReturn(response);
assertThat(requester.request("URI")).isEqualTo(response);
}
Note that it appears both on the Mockito
class and on the Answers
enum, so it is also be compatible with @Mock(answer = RETURNS_SELF)
syntax.
The problem with using RETURN_DEEP_STUBS is that you'll get a different mock each time you call a method. I think from your question that you want to use a default Answer that actually returns the mock on which it was called, for each method that has the right return type. This could look something like the following. Note that I haven't tested this, so it may contain typos, but I hope that the intention is clear in any case.
import static org.mockito.Mockito.RETURNS_DEFAULTS;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;
public class SelfReturningAnswer implements Answer<Object> {
public Object answer(InvocationOnMock invocation) throws Throwable {
Object mock = invocation.getMock();
if(invocation.getMethod().getReturnType().isInstance(mock)){
return mock;
}
return RETURNS_DEFAULTS.answer(invocation);
}
}
Then, when you create your mock, specify this as your default answer. This will make your mock return itself from each method that it can; but it will behave like an ordinary mock when you call a method whose return type is wrong for the mock.
Create your mock like this
Builder mockBuilder = mock( Builder.class, new SelfReturningAnswer());
or create a constant for this class and write something like
@Mock(answer = SELF_RETURNING) private Builder mockBuilder;
Hope that helps.