Mockito如何在thenReturn块中处理具有多个参数的重叠匹配器

Cla*_*ton 9 java mockito

我有一块测试代码试图在通用情况下在后续调用中返回两个值,但在特定情况下只返回与该情况相关的值.代码看起来像:

when(mockObject.method(anyString())).thenReturn(string1, string2);
when(mockObject.method(eq("expectedInput1"))).thenReturn(string1);
when(mockObject.method(eq("expectedInput2"))).thenReturn(string2);
Run Code Online (Sandbox Code Playgroud)

预期的行为是,当调用mockObject.method("foo")mockObject.method("bar"),string1并且string2应该分别返回时,但测试实际上是看到了两个响应string2.这是一个错误Mockito吗?或者我误解了Mockito模式匹配.

我的假设是匹配的最后一个模式是返回的,但是当经历该过程时,是否分别Mockito处理第一个thenReturn块中的每个参数?有没有办法绕过这种行为?

当我在调用时注释掉第二个时,模拟的行为与预期一致,所以我假设有一些关于重叠匹配器行为的特定内容.

编辑:这是Mockito版本1.9.5

Ash*_*eze 12

我今天遇到了这个问题.它是由调用mock来设置实际消耗已存在的存根的存根引起的.

在此示例中,将第一行更改为

when(mock.call(anyString())).thenReturn("","",string1,string2)
Run Code Online (Sandbox Code Playgroud)

当您设置其他模拟返回时,这将为您提供两个空白响应,将string1作为第一个有用的返回值.

尝试doReturn替代方案,我认为可能没有这些问题:

doReturn(string1,string2).when(mock).call(anyString());
Run Code Online (Sandbox Code Playgroud)

这在设置期间使用不同的存根.

所以我对此做了更多的研究.根据OP的问题,这是我正在玩的功能:

    Function<String, String> function = mock(Function.class);
    when(function.apply(anyString())).thenReturn("A","B","C");
    when(function.apply("Jim")).thenReturn("Jim");
    when(function.apply("Bob")).thenReturn("Bob");

    assertThat(function.apply("Jim")).isEqualTo("Jim");
    assertThat(function.apply("Bob")).isEqualTo("Bob");
    assertThat(function.apply("")).isEqualTo("A");
    assertThat(function.apply("")).isEqualTo("B");
    assertThat(function.apply("")).isEqualTo("C");
    assertThat(function.apply("")).isEqualTo("C");
Run Code Online (Sandbox Code Playgroud)

上面的失败是isEqualTo("A")因为两次调用设置模拟JimBob从提供的列表中使用返回值anyString().

你可能会试图重新排序这些when子句,但是失败了,因为它anyString()取代了特殊情况,因此也失败了.

以上版本的上述DOES按预期工作:

    when(function.apply(anyString())).thenReturn("A","B","C");

    doReturn("Jim")
        .when(function)
        .apply("Jim");
    doReturn("Bob")
        .when(function)
        .apply("Bob");

    assertThat(function.apply("Jim")).isEqualTo("Jim");
    assertThat(function.apply("Bob")).isEqualTo("Bob");
    assertThat(function.apply("")).isEqualTo("A");
    assertThat(function.apply("")).isEqualTo("B");
    assertThat(function.apply("")).isEqualTo("C");
    assertThat(function.apply("")).isEqualTo("C");
Run Code Online (Sandbox Code Playgroud)

这是因为该doReturn技术旨在修改飞行中预先存在的模拟,实际上并不涉及在模拟上调用方法来设置模拟.

你可以使用doReturn所有的设置,而不是之间的混合when... thenReturndoReturn... when... function().碰巧,这有点丑陋:

    doReturn("A").doReturn("B").doReturn("C")
        .when(function)
        .apply(anyString());
Run Code Online (Sandbox Code Playgroud)

没有方便的varargs功能让您按顺序指定多个返回.不过,上面已经过测试并且确实有效.