Anthony Kong
Anthony Kong

Reputation: 40624

How to return the argument passed to a Mockito-mocked method in the thenReturn function?

This is what I want to achieve.

MyClass doSomething =  mock(MyClass.class);
when(doSomething.perform(firstParameter, any(Integer.class), any(File.class)))
    .thenReturn(firstParameter);

Basically I want the mocked class's method to always return the first argument that was passed into the method.

I have tried to use ArgumentCaptor, like so

ArgumentCaptor<File> inFileCaptor = ArgumentCaptor.forClass(File.class);
MyClass doSomething = mock(MyClass.class);
when(doSomething.perform(inFileCaptor.capture(), any(Integer.class), any(File.class)))
    .thenReturn(firstParameter);

But mockito just failed with this error message:

No argument value was captured!
You might have forgotten to use argument.capture() in verify()...
...or you used capture() in stubbing but stubbed method was not called.
Be aware that it is recommended to use capture() only with verify()

Examples of correct argument capturing:
    ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
    verify(mock).doSomething(argument.capture());
    assertEquals("John", argument.getValue().getName());

I think the ArgumentCaptor class only works with verify calls.

So how can I return the first parameter as passed-in during test?

Upvotes: 5

Views: 6427

Answers (2)

Fred
Fred

Reputation: 17085

You do this usually with thenAnswer:

when(doSomething.perform(firstParameter, any(Integer.class), 
             any(File.class)))
    .thenAnswer(new Answer<File>() {
          public File answer(InvocationOnMock invocation) throws Throwable {
        return invocation.getArgument(0);
    }
 };

and you can simplify this to be

when(doSomething.perform(firstParameter, any(Integer.class), any(File.class)))
  .thenAnswer(invocation -> invocation.getArgument(0));

Upvotes: 7

marok
marok

Reputation: 2146

You can also do with org.mockito.AdditionalAnswers

when(doSomething.perform(eq(firstParameter), any(Integer.class), any(File.class)))
    .thenAnswer(AdditionalAnswers.returnsFirstArg())

Also @Fred solution could be written with lambda

when(doSomething.perform(eq(firstParameter), any(Integer.class), any(File.class)))
        .thenAnswer(i->i.getArgument(0));

Upvotes: 6

Related Questions