Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can Mockito capture arguments passed to an injected mock object's methods?

I am trying to test a service class, which internally makes use of a Spring AMQP connection object. This connection object is injected by Spring. However, I don't want my unit test to actually communicate with the AMQP broker, so I am using Mockito inject a mock of the connection object.

/**   * The real service class being tested.  Has an injected dependency.   */  public class UserService {     @Autowired    private AmqpTemplate amqpTemplate;     public final String doSomething(final String inputString) {       final String requestId = UUID.randomUUID().toString();       final Message message = ...;       amqpTemplate.send(requestId, message);       return requestId;    } }  /**   * Unit test   */ public class UserServiceTest {     /** This is the class whose real code I want to test */    @InjectMocks    private UserService userService;     /** This is a dependency of the real class, that I wish to override with a mock */    @Mock    private AmqpTemplate amqpTemplateMock;     @Before    public void initMocks() {       MockitoAnnotations.initMocks(this);    }     @Test    public void testDoSomething() {       doNothing().when(amqpTemplateMock).send(anyString(), any(Message.class));        // Call the real service class method, which internally will make        // use of the mock (I've verified that this works right).       userService.doSomething(...);        // Okay, now I need to verify that UUID string returned by        // "userService.doSomething(...) matches the argument that method        // internally passed to "amqpTemplateMock.send(...)".  Up here        // at the unit test level, how can I capture the arguments passed        // to that inject mock for comparison?       //       // Since the value being compared is a UUID string created        // internally within "userService", I cannot just verify against        // a fixed expected value.  The UUID will by definition always be       // unique.    } } 

The comments in this code sample hopefully lay out the question clearly. When Mockito injects a mock dependency into a real class, and unit tests on the real class cause it to make calls to the mock, how can you later retrieve the exact arguments that were passed to the injected mock?

like image 674
Steve Perkins Avatar asked Mar 20 '15 15:03

Steve Perkins


1 Answers

Use one, or more, ArgumentCaptors.

It is unclear what your types are here, but anyway. Let's suppose you have a mock which has a method doSomething() taking a Foo as an argument, then you do this:

final ArgumentCaptor<Foo> captor = ArgumentCaptor.forClass(Foo.class);  verify(mock).doSomething(captor.capture());  final Foo argument = captor.getValue();  // Test the argument 

Also, it looks like your method returns void and you don't want it to do anything. Just write this:

doNothing().when(theMock).doSomething(any()); 
like image 182
fge Avatar answered Oct 20 '22 00:10

fge