Mockito-是否存在“不在列表中的值”的匹配项?

时间:2018-08-14 14:36:46

标签: java unit-testing junit mockito

我目前有一个模拟,它具有针对特定输入集的特定行为。 其他所有输入都应返回特定的响应。

例如:

    Mockito.when(classInstance.myFunc(Mockito.eq("Option1"))).thenReturn(answer1);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option2"))).thenReturn(answer2);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option3"))).thenReturn(answer3);
    Mockito.when(classInstance.myFunc(Mockito.eq("Option4"))).thenReturn(answer4);

    // Return defaultAnswer if and(and(not("Option1"), not("Option2")), and(not("Option3"), not("Option4")))
    Mockito.when(classInstance.myFunc(AdditionalMatchers.and(AdditionalMatchers.and(AdditionalMatchers.not(Mockito.eq("Option1")), AdditionalMatchers.not(Mockito.eq("Option2")), AdditionalMatchers.and(AdditionalMatchers.not(Mockito.eq("Option3")), AdditionalMatchers.not(Mockito.eq("Option4")))).thenReturn(defaultAnswer);

我最大的麻烦是and(and(not("Option1"), not("Option2")), and(not("Option3"), not("Option4")))行的复杂性。

我真的希望有一种更简便的方法来指定“其他所有条件”或只是“不在列表中:[“ option1”,...]“

在“组内”或类似名称中有匹配器吗?

3 个答案:

答案 0 :(得分:3)

  

我目前有一个模拟,它具有针对特定输入集的特定行为。其他所有输入都应返回特定的响应。

就像,错。

单元测试的目的是使您迅速发现一个错误。为了了解发生了什么,您希望单元测试尽可能地“独立”。您阅读了测试,也许是设置方法,并且了解了正在发生的事情(或者至少:“进入”正在测试的代码)。

拥有多个规范来涵盖多个案例并没有帮助,相反。你不要那样

相反,您需要尽可能少的规格。如果您的模拟看到不同的输入,并且应该返回不同的结果,那么应该按 per 测试用例进行操作。在您的设置方法中,不是“一般”。

因此,独特的非答案:避免具有这样的多种规格。

答案 1 :(得分:3)

为什么不简单使用Mockito.matches(boolean)如:

 import static org.mockito.Mockito.*;

 Mockito.when(classInstance.myFunc(matches("Option[^1-4]"))
        .thenReturn(defaultAnswer);

您也可以使用Mockito.argThat()
要过滤掉一些整数值(如您的注释中所建议),您可以编写:

 import static org.mockito.Mockito.*;

 List<Integer> toNotMatchList = Arrays.asList(1, 2, 3, 4) ;
 Mockito.when(classInstance.myFunc(argThat(i -> !toNotMatchList.contains(i))
        .thenReturn(defaultAnswer);

或更直接地:

Mockito.when(classInstance.myFunc(argThat(i -> !Arrays.asList(1, 2, 3, 4).contains(i))
        .thenReturn(defaultAnswer);

答案 2 :(得分:2)

通过显式定义默认值,然后通过后续存根“覆盖”它,可能会使其更具可读性:

when(classInstance.myFunc(any()).thenReturn(defaultAnswer);
when(classInstance.myFunc("Option1").thenReturn(answer1);
when(classInstance.myFunc("Option2").thenReturn(answer2);
...

或者您可以使用MockitoHamcrest和Hamcrest的核心匹配器来简化它,例如:

when(classInstance.myFunc(argThat(is(allOf(not("Option1"), not("Option2"), ...))))
    .thenReturn(...)

或者您可以使用MockitoHamcrest和您自己的Hamcrest匹配器。