Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intercept object on method invocation with Mockito

I've a mocked class with a void method like

public class Mock {
    public void method(String string) {
        // doSomething
    }
}

I don't care about what this method does but I would like to get the String sent.

This String is actually an object in a JSON format, and the method that I'm testing is modifying this object depending on the String originally sent (quite random let's say).

method(String json) {
    Object obj = unparse(json);
    obj.setRandomValue(random);
    String parsed = parse(obj);
    Mock.method(parsed);
}

I would like just to see if the "randomValue", previously null, is actually set with the random after the method invocation.

The best would be to intercept the json, parse it and check the object.

like image 784
Enrichman Avatar asked Sep 03 '12 08:09

Enrichman


People also ask

What is invocation on mock?

public interface Invocation extends InvocationOnMock, DescribedInvocation. A method call on a mock object. Contains all information and state needed for the Mockito framework to operate. This API might be useful for developers who extend Mockito.

Can I mock objects in Mockito?

The Mockito. mock() method allows us to create a mock object of a class or an interface. We can then use the mock to stub return values for its methods and verify if they were called. We don't need to do anything else to this method before we can use it.

How does @mock work in Mockito?

With Mockito, you create a mock, tell Mockito what to do when specific methods are called on it, and then use the mock instance in your test instead of the real thing. After the test, you can query the mock to see what specific methods were called or check the side effects in the form of changed state.

What is the use of when thenReturn in Mockito?

The thenReturn() methods lets you define the return value when a particular method of the mocked object is been called.


3 Answers

You are looking for an ArgumentCaptor:

  Mock mock =  Mockito.mock(Mock.class);
  ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
  mock.method("input");
  Mockito.verify(mock).method(captor.capture());
  String actualValue = captor.getValue();
like image 93
Urs Reupke Avatar answered Sep 25 '22 15:09

Urs Reupke


There is one more way to do this, here is example:

Mock mock =  Mockito.mock(Mock.class);
when(mock.method(any(String.class))).thenAnswer(new Answer<Void>() {

        @Override
        public Void answer(InvocationOnMock invocation) throws Throwable {
            String actualValue = invocation.getArgumentAt(0, String.class);
            Assert.assertEquals("input", actualValue);
            return null;
        }
    });
// Test your method 
mock.method("input");
Mockito.verify(mock, Mockito.times(1)).method("input");
like image 28
Mindaugas Jaraminas Avatar answered Sep 26 '22 15:09

Mindaugas Jaraminas


Just refining answer from @softarn to match OP's example, Reference here

Mock mock =  Mockito.mock(Mock.class);
ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).method(argument.capture());
assertEquals("{some pretty json string}", argument.getValue());
like image 29
nilesh Avatar answered Sep 22 '22 15:09

nilesh