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

前端 未结 2 605
悲哀的现实
悲哀的现实 2020-12-28 12:24

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

相关标签:
2条回答
  • 2020-12-28 12:43

    You can hook doAnswer() to the stub of the send() method on amqpTemplateMock and then capture the invocation arguments of AmqpTemplate.send().

    Make the first line of your testDoSomething() be this

        Mockito.doAnswer(new Answer<Void>() {
              @Override
              public Void answer(final InvocationOnMock invocation) {
                final Object[] args = invocation.getArguments();
                System.out.println("UUID=" + args[0]);  // do your assertions here
                return null;
              }
        }).when(amqpTemplateMock).send(Matchers.anyString(), Matchers.anyObject());
    

    putting it all together, the test becomes

    import org.junit.Before;
    import org.junit.Test;
    import org.mockito.InjectMocks;
    import org.mockito.Matchers;
    import org.mockito.Mock;
    import org.mockito.Mockito;
    import org.mockito.MockitoAnnotations;
    import org.mockito.invocation.InvocationOnMock;
    import org.mockito.stubbing.Answer;
    
    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() throws Exception {
        Mockito.doAnswer(new Answer<Void>() {
          @Override
          public Void answer(final InvocationOnMock invocation) {
            final Object[] args = invocation.getArguments();
            System.out.println("UUID=" + args[0]);  // do your assertions here
            return null;
          }
        }).when(amqpTemplateMock).send(Matchers.anyString(), Matchers.anyObject());
        userService.doSomething(Long.toString(System.currentTimeMillis()));
      }
    }
    

    This gives output

    UUID=8e276a73-12fa-4a7e-a7cc-488d1ce0291f

    I found this by reading this post, How to make mock to void methods with mockito

    0 讨论(0)
  • 2020-12-28 12:55

    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());
    
    0 讨论(0)
提交回复
热议问题