Causes the simulation method to return the parameters passed to it

Posted by SkillsToShow on Fri, 03 Jan 2020 12:35:33 +0100

Consider signing as follows:

public String myFunction(String abc);

Can Mockito help return the same string that the method received?

#1 building

If you have Mockito 1.9.5 or later, there is a new static method to create an Answer object for you. You need to write something like

import static org.mockito.Mockito.when;
import static org.mockito.AdditionalAnswers.returnsFirstArg;

when(myMock.myFunction(anyString())).then(returnsFirstArg());

perhaps

doAnswer(returnsFirstArg()).when(myMock).myFunction(anyString());

Note that the returnsfirsarg() method is static in the AdditionalAnswers class and is a new feature of Mockito 1.9.5. So you need the correct static import.

#2 building

You can create answers in Mockito. Suppose we have an interface called Application with the method myFunction.

public interface Application {
  public String myFunction(String abc);
}

This is the test method with Mockito's answer:

public void testMyFunction() throws Exception {
  Application mock = mock(Application.class);
  when(mock.myFunction(anyString())).thenAnswer(new Answer<String>() {
    @Override
    public String answer(InvocationOnMock invocation) throws Throwable {
      Object[] args = invocation.getArguments();
      return (String) args[0];
    }
  });

  assertEquals("someString",mock.myFunction("someString"));
  assertEquals("anotherString",mock.myFunction("anotherString"));
}

Starting with Mockito 1.9.5 and Java 8, using the lambda function provides an easier way:

when(myMock.myFunction(anyString())).thenAnswer(i -> i.getArguments()[0]);

#3 building

With Java 8, you can create a single line answer even with an older version of Mockito:

when(myMock.myFunction(anyString()).then(i -> i.getArgumentAt(0, String.class));

Of course, this is not as useful as using the AdditionalAnswers suggested by David Wallace, but it can be useful if you want to convert parameters "on the fly.".

#4 building

Using Java 8, Steve's answer Can become

public void testMyFunction() throws Exception {
    Application mock = mock(Application.class);
    when(mock.myFunction(anyString())).thenAnswer(
    invocation -> {
        Object[] args = invocation.getArguments();
        return args[0];
    });

    assertEquals("someString", mock.myFunction("someString"));
    assertEquals("anotherString", mock.myFunction("anotherString"));
}

Edit: shorter:

public void testMyFunction() throws Exception {
    Application mock = mock(Application.class);
    when(mock.myFunction(anyString())).thenAnswer(
        invocation -> invocation.getArgument(0));

    assertEquals("someString", mock.myFunction("someString"));
    assertEquals("anotherString", mock.myFunction("anotherString"));
}

#5 building

You may want to use verify() with ArgumentCaptor to ensure execution in your tests, and ArgumentCaptor can evaluate parameters:

ArgumentCaptor<String> argument = ArgumentCaptor.forClass(String.class);
verify(mock).myFunction(argument.capture());
assertEquals("the expected value here", argument.getValue());

The value of the parameter can obviously be accessed through arguments.getValue() for further operations / checks / anyway.

Topics: Java Lambda