Fine Grained Stub Behavior With Mockito
Continuing a trend of Mockito related articles, I thought I’d blog about using another feature I recently discovered while trying to figure out how to implement fine grained behavior in mockito.
First, let me set the stage… I had a method call I was writing examples for that was a typical Castor marshal operation, which often looks something like this:
StringWriter w = new StringWriter(); marshaller.setWriter(w); marshaller.marshal(obj); channel.send(w.toString());
Yeah I know… it looks like shit. But sometimes APIs force that on you. Anyway, I wanted to write an example illustrating that the channel received a message that was the result of whatever marshaller wrote to the output stream, but this was a little difficult to do (but easy to do with hard coded subclasses and lots and lots of boilerplate code).
The answer comes with, well, the Answer interface. To illustrate this, let me set up an example. Given I have started a unit test that looks like this:
@RunWith(MockitoJUnitRunner.class)
public class MessageServiceTest {
@Mock private Marshaller marshaller;
@Mock private Channel channel;
private MessageServiceImpl messagService;
@Before
public void before(){
messagService = new MessageServiceImpl();
messagService.setChannel(channel);
messagService.setMarshaller(marshaller);
}
@Test
public void shouldWriteMarshalledDataOutToChannel(){
}
}
We want to be able to verify that the channel (which is a simple interface with a send(String arg) method) receives whatever String the marshaller wrote to the provided Writer. Now, because the writer is constructed in the class itself, it’s difficult to stub this out. So in order to make the writer have SOMETHING written to it, we set up an answer to be invoked both when marshaller.setWriter(..) and when the marshaller.marshall(..) method is called:
private class MarshalAnswer{
private Writer writer;
public Answer<Writer> respondToSetWriter(){
return new Answer<Writer>() {
public Writer answer(InvocationOnMock invocation) throws Throwable {
Writer w = (Writer) invocation.getArguments()[0];
writer = w;
return null;
}
};
}
public Answer<Object> respondToMarshall(final String writeThis){
return new Answer<Object>(){
public Object answer(InvocationOnMock invocation)
throws Throwable {
writer.write(writeThis);
return null;
}
};
}
}
Bleh… lots and lots of boilerplate code because of the interfaces, but oh well. Here’s the revised test case in action:
@RunWith(MockitoJUnitRunner.class)
public class MessageServiceTest {
@Mock private Marshaller marshaller;
@Mock private Channel channel;
private MessageServiceImpl messageService;
private Invoice invoice;
private MarshalAnswer answers;
@Before
public void before(){
messageService = new MessageServiceImpl();
messageService.setChannel(channel);
messageService.setMarshaller(marshaller);
invoice = new Invoice();
answers = new MarshalAnswer();
}
@Test
public void shouldWriteMarshalledDataOutToChannel() throws Exception{
doAnswer(answers.respondToSetWriter()).when(marshaller).setWriter(any(Writer.class));
doAnswer(answers.respondToMarshall("<someresult/>")).when(marshaller).marshal(invoice);
messageService.send(invoice);
verify(channel).send("<someresult/>");
}
...
I could have just created the respondTo methods in the TestCase itself, but I wanted to keep it separated by putting it in a helper class.
So now we run the test and we should see the following:

Fair enough… lets add the following code to the method we’re describing and rerun:
public void send(Invoice invoice) throws Exception{
StringWriter writer = new StringWriter();
marshaller.setWriter(writer);
marshaller.marshal(invoice);
channel.send(writer.getBuffer().toString());
}
We rerun and sure enough, green bar! The way it works is pretty simple… whenever setWriter gets invoked, the Answer object gets called and the argument is available within it (in this case the writer) which we can then store to use for the marshal call. When marshal gets called, our Answer we defined gets called and writes whatever we told it to.
While this does provide us with a useful tool when requiring some slightly complex behavior in our collaborator interactions (in this case, we essentially needed to capture what was passed to the writer, which was acting as a hidden output variable) I’d still recommend avoiding them when you can. ![]()
If you're new here, you may want to subscribe to my RSS feed. Thanks for visiting!














October 19th, 2009 at 5:17 pm
As usual, I couldn’t resist to try your example with Spock. Here is the result (full code):
class MessageServiceTest extends Specification { def marshaller = Mock(Marshaller) def channel = Mock(Channel) def messageService = new MessageServiceImpl() def invoice = new Invoice() def setup() { messageService.channel = channel messageService.marshaller = marshaller } def "should write marshalled data out to channel"() { when: messageService.send(invoice) then: def writer marshaller.setWriter(_) >> { writer = it[0] } marshaller.marshall(invoice) >> { writer.write("") } 1 * channel.send("") } }October 19th, 2009 at 6:56 pm
Seems like the “someResult” element passed to writer.write() and channel.send() got lost in translation, but everything else is there.
October 20th, 2009 at 9:05 am
It seems I am overdue to write a post on spock
January 25th, 2010 at 2:51 am
Hi:
I liked your code examples for Mockito!!!
Is there a link where I can download the code?
Yours,
John Smith