mockito回调和获取参数值

nfl*_*cco 70 java mockito

我没有运气让Mockito捕获函数参数值!我正在嘲笑搜索引擎索引而不是构建索引,我只是使用哈希.

// Fake index for solr
Hashmap<Integer,Document> fakeIndex;

// Add a document 666 to the fakeIndex
SolrIndexReader reader = Mockito.mock(SolrIndexReader.class);

// Give the reader access to the fake index
Mockito.when(reader.document(666)).thenReturn(document(fakeIndex(666))
Run Code Online (Sandbox Code Playgroud)

我不能使用任意参数,因为我正在测试查询的结果(即他们返回哪些文档).同样,我不想为每个文档指定一个特定的值并且有一行!

Mockito.when(reader.document(0)).thenReturn(document(fakeIndex(0))
Mockito.when(reader.document(1)).thenReturn(document(fakeIndex(1))
....
Mockito.when(reader.document(n)).thenReturn(document(fakeIndex(n))
Run Code Online (Sandbox Code Playgroud)

我查看了使用Mockito页面上的回调部分.不幸的是,它不是Java,我无法用Java自己解释它.

编辑(澄清):如何让Mockito获取参数X并将其传递给我的函数?我想要传递给函数的X的确切值(或ref).

我不想枚举所有情况,并且任意参数将不起作用,因为我正在测试不同查询的不同结果.

Mockito页面说

val mockedList = mock[List[String]]
mockedList.get(anyInt) answers { i => "The parameter is " + i.toString } 
Run Code Online (Sandbox Code Playgroud)

这不是java,我不知道如何转换成java或传递给函数发生的事情.

Ed *_*aub 91

我从来没有使用Mockito,但想学习,所以这里.如果有人比我更无能为力,请先试试他们的答案!

Mockito.when(reader.document(anyInt())).thenAnswer(new Answer() {
 public Object answer(InvocationOnMock invocation) {
     Object[] args = invocation.getArguments();
     Object mock = invocation.getMock();
     return document(fakeIndex((int)(Integer)args[0]));
     }
 });
Run Code Online (Sandbox Code Playgroud)

  • 我刚刚注意到右侧的链接[Mockito:如何使方法返回传递给它的参数](http://stackoverflow.com/questions/2684630/mockito-how-to-make-a-方法返回-AN-参数 - 即,被旁路到它).看起来我很亲密,如果没有发现. (2认同)

qua*_*ial 51

查看ArgumentCaptors:

http://site.mockito.org/mockito/docs/1.10.19/org/mockito/ArgumentCaptor.html

ArgumentCaptor<Integer> argument = ArgumentCaptor.forClass(Integer.class);
Mockito.when(reader.document(argument.capture())).thenAnswer(
  new Answer() {
    Object answer(InvocationOnMock invocation) {
      return document(argument.getValue());
    }
  });
Run Code Online (Sandbox Code Playgroud)

  • 哇,我不知道你可以使用 `ArgumentCaptor`s ​​进行存根。不过,该链接中有一个很大的警告。谨慎行事。 (3认同)
  • 是的,你是对的.绑架者只能用于验证. (2认同)

fl0*_*l0w 27

您可能希望将verify()与ArgumentCaptor结合使用以确保在测试中执行,并使用ArgumentCaptor来评估参数:

ArgumentCaptor<Document> argument = ArgumentCaptor.forClass(Document.class);
verify(reader).document(argument.capture());
assertEquals(*expected value here*, argument.getValue());
Run Code Online (Sandbox Code Playgroud)

参数的值显然可以通过argument.getValue()进行进一步的操作/检查或任何你想做的事情.

  • 最佳答案: 简单易懂 (2认同)
  • 因为它没有回答问题。是的,当你想要捕获参数时,ArgumentCaptor 非常有用,但是你不能将它与 when(...).thenReturn() 结合使用,这正是 OP 试图做的事情:基于某个参数,模拟服务应该返回一个特定的对象。 (2认同)

Jea*_*hef 10

使用Java 8,这可能是这样的:

Mockito.when(reader.document(anyInt())).thenAnswer(
  (InvocationOnMock invocation) -> document(invocation.getArguments()[0]));
Run Code Online (Sandbox Code Playgroud)

我假设这document是一张地图.