Mockito returnFirstArg()使用

我已经开始使用Mockito AdditionalAnswers#returnsFirstArg ,这很棒:

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

但我想知道是否有一种简单的方法来提取输入参数,以便在例如构造函数中使用:

 when(myMock.myFunction(anyString())).thenReturn(new MyObject((String)returnsFirstArg())); 

(这显然不起作用……)

最简单的(只有?)方法,恕我直言,将使用thenAnswer方法,它允许您不仅返回一个值,而且实际执行一些代码。 Java 8使这个特别优雅,因为您可以使用匿名lambda:

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

我想你可能需要一个帮助类AnswerPipeline ,我将介绍它如何使测试更具可读性 ,更具表现力和更有趣

注意 :您可以通过AnswerPipeline#will(Answer)方法AnswerPipeline#will(Answer)任何Answer转换为AnswerPipeline ,而不仅仅是returnsFirstArg()

然后使用语法糖来描述测试,例如:

 Function function = mock(Function.class); when(function.apply(anyString())).then( /**/ will(returnsFirstArg()) // adapt an Answer to an AnswerPipeline /**/.as(String.class) // set the result type /**/.to(String::toUpperCase) // transforming the result ); assertThat(function.apply("first"), equalTo("FIRST")); 

然后很容易解决你的问题没有困难:

 when(myMock.myFunction(anyString())) .then(will(returnsFirstArg()).as(String.class).to(MyObject::new)); 

AnswerPipeline类

 interface AnswerPipeline extends Answer { static  AnswerPipeline will(Answer answer) { return answer::answer; } default  AnswerPipeline as(Class type) { return to(type::cast); } default  AnswerPipeline to(Function mapper) { return it -> mapper.apply(answer(it)); } } 

您可以使用thenAnswer方法并创建一个Answer来获取参数:

 when(myMock.myFunction(anyString())).thenAnswer(new Answer() { @Override public MyObject answer(InvocationOnMock invocation) throws Throwable { String s = invocation.getArgument(0); // get first argument return new MyObject(s); } }); 

如果您使用的是java 8,则可以使用lambda语法:

 when(myMock.myFunction(anyString())) .thenAnswer(args -> new MyObject(args.getArgument(0))); 

备注

  • 我不需要将invocation.getArgument(0)强制转换为String ,但是根据你的java / mockito版本,也许它是必要的: (String) invocation.getArgument(0)
  • 取决于你的mockito版本, getArgument(int)方法可能不存在,你应该使用getArgumentAt(int, Class) (在这种情况下,调用将是getArgumentAt(0, String.class) )。 或者您可以使用getArguments()[0]并将其getArguments()[0]String