如何 return 将参数传递给 thenReturn 函数中的 Mockito 模拟方法?

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

这就是我想要实现的。

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

基本上我希望模拟的 class 方法总是 return 传递给方法的第一个参数。

我试过ArgumentCaptor,像这样

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);

但是 mockito 刚刚失败并显示此错误消息:

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());

我认为 ArgumentCaptor class 仅适用于 verify 调用。

那么我如何return测试时传入的第一个参数?

您通常使用 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);
    }
 };

你也可以用 org.mockito.AdditionalAnswers

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

@Fred 解决方案也可以用 lambda 编写

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