Posts tagged ‘Mockito’

Complex Stubbing with Mockito for Java

2013-02-01 6:33

Mocks are used to “fake” the behavior of objects to the extent required by tests. Most of the time, they can be pretty simple: when calling a method with given set of (constant) argument, then return some predefined value. Mocking frameworks actually strive to translate the previous sentence directly into code, which can be seen in Java’s Mockito library:

  1. @Mock private SomeBuilder someBuilder;
  2. @Mock private SomeObject someObject;
  3.  
  4. private void mockSomeBuilder() {
  5.     when(someBuilder.setFoo(anyString())).thenReturn(someBuilder);
  6.     when(someBuilder.setBar(anyInt())).thenReturn(someBuilder);
  7.     when(someBuilder.build()).thenReturn(someObject);
  8. }

What is evident here is that this mock doesn’t maintain any state. As a result, all stubbed method are completely independent and referentially transparent: they always return the same value for the same set of arguments. In reality, that property is even stronger because they are simply constant.

Simple mocks like those work for a good number of cases. Some may even argue that it’s the only way to mock properly, because anything more complicated is a sign of code smell. We can counter that by saying that some complexity is often unavoidable, and it’s up to developers to decide whether they want to put it test or tested code.

And thus more complex stubbing may be needed if, for some case, you prefer the former approach. When that happens, it’s good to know how to fabricate a bit more sophisticated behavior. In Mockito, it’s very possible to achieve almost arbitrary complexity by capturing arguments of stubbed calls and routing them to callbacks. This is done with the help of ArgumentCaptor class and the Answer interface, respectively.
When combined, they can result in pretty clever mocks, as illustrated with this example of some imaginary API for SMTP (e-mail sending protocol):

  1. @Mock private SmtpConnection smtpConnection;
  2.  
  3. private void mockSmtpConnection() {
  4.     final ArgumentCaptor<String> recipient = ArgumentCaptor.forClass(String.class);
  5.     final ArgumentCaptor<String> subject = ArgumentCaptor.forClass(String.class);
  6.     final ArgumentCaptor<String> body = ArgumentCaptor.forClass(String.class);
  7.  
  8.     when(smtpConnection.setRecipient(recipient.capture()))
  9.         .thenReturn(smtpConnection);
  10.     when(smtpConnection.setSubject(subject.capture()))
  11.         .thenReturn(smtpConnection);
  12.     when(smtpConnection.setMessage(body.capture()))
  13.         .thenReturn(smtpConnection);
  14.  
  15.     when(smtpConnection.getOutgoingClientData())
  16.         .thenAnswer(new Answer<String> {
  17.         @Override
  18.         public String answer(InvocationOnMock call) {
  19.             return recipient.getValue() + "\0"
  20.                 + subject.getValue() + "\0"
  21.                 + body.getValue();
  22.         }
  23.     });
  24. }

Note that it doesn’t implement the real SMTP. That, presumably, would mimic the SmtpConnection class exactly, which of course is not the point of mocking at all.
The point is to provide sufficiently complete behavior so that code under test can proceed, reaching all the execution paths we want to exercise. In this case, something can call getOutgoingClientData and rely on certain string being present in the output.

Let’s just hope that this “something” actually has some good reasons to expect that…

Tags: , , , ,
Author: Xion, posted under Computer Science & IT » Comments Off on Complex Stubbing with Mockito for Java
 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.