【问题标题】:Return argument of mocked method as a result结果返回模拟方法的参数
【发布时间】:2015-06-23 20:17:54
【问题描述】:

最简单的例子:我有以下方法:

public String testMethod(String arg){
    .....
}

我想模拟这个方法以返回传递的参数作为结果。例如:

testMethod("aString") returns "aString"
testMethod("anotherString") returns "anotherString"

我知道我可以硬编码这种行为,但我希望它是通用的。

【问题讨论】:

标签: java junit mockito


【解决方案1】:

你可以自己写Answer:

when(mock.testMethod(anyString())).thenAnswer(new Answer<String>() {
    @Override
    public String answer(InvocationOnMock invocation) {
        return invocation.getArgumentAt(0, String.class);
    }
});

或者:

when(mock.testMethod(anyString()))
    .thenAnswer(AdditionalAnswers.<String>returnsFirstArg());

【讨论】:

  • 感谢您的回复,它解决了我的问题!第二个解决方案返回 null,但第一个解决方案非常适合。我尝试过类似的方法: when(mock.testMethod(anyString())).thenReturn(returnsArgAt(0).toString());但在我的情况下它不起作用,可能是我做错了什么。
  • @Jean:避免使用ClonesArguments,因为它是一个内部包; AdditionalAnswers 是去那里的方法。 Aram:thenReturn 将始终在存根时计算并保存一个值,这在您需要它之前很久。使用 thenAnswer(returnArgAt(0)) 告诉 Mockito 使用答案来计算值,特别是 returnsArgAt(0) 给出的答案,所以你不应该在那里调用 toString
  • @JeffBowman 你是对的,我没有注意到它是内部的。我删除它并切换到AdditionalAnswers
【解决方案2】:

你可以实现你自己的Answer:

Answer<String> returnArgAnswer = new Answer<String>() {
    public String answer(InvocationOnMock invocationOnMock) throws Throwable {
        return (String) invocationOnMock.getArguments()[0];
    }
};

SomeClass x = mock(SomeClass.class);
Mockito.when(x.testMethod(anyString())).thenAnswer(returnArgAnswer);

然后,使用任何字符串调用x.testMethod 都会返回该字符串。

【讨论】:

    【解决方案3】:

    这已经内置在 Mockito 1.9.5 及更高版本中,如 returnsFirstArg

    when(mock.testMethod(anyString())).thenAnswer(returnsFirstArg());
    

    您可能希望避免直接使用ClonesArguments,因为它位于内部包org.mockito.internal.stubbing.answers 中。 Mockito 的静态工厂类是获取 Mockito 预定义答案和匹配器的首选方式。

    【讨论】:

      【解决方案4】:

      这样写:

      public String testMethod(String arg){
          return arg;
      }
      

      【讨论】:

      • 我需要模拟这种行为进行测试,我不想更改它的代码。
      • @AramAslanyan 我不太确定您对“模拟”的含义是什么。我不是说英语的人,我在翻译中搜索,我认为这句话对我来说没有意义。
      • 这是 Mockito 框架中的一个术语:当你想拥有具有相似行为的假对象时,你可以模拟对象。
      【解决方案5】:

      通用-通用?您可以使用以下

      public <T> T testMethod(T arg) {
          return arg;
      }
      

      那么你可以用任何类型,

      String s = testMethod("someString");
      Integer i = testMethod(0);
      

      【讨论】:

      • 不,这不是 OP 想要的。他想模拟该方法以准确返回他传递给该方法的字符串。他的意思是“通用”,他不想在when(...).then(...) 语句中使用字符串文字。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-12
      相关资源
      最近更新 更多