使用Mockito模拟方法行为时以任何顺序匹配List

Vin*_*t F 5 java unit-testing mockito

我有一个使用Mockito的测试有一个非常奇怪的行为:它在调试中工作但在正常运行时失败.经过一番调查后,我意识到这是因为我在嘲笑方法行为,传递一系列要匹配的元素.但由于某种原因,列表中的顺序并不总是相同,所以它不匹配,我期望我的模拟返回不返回,因为2个列表不是"等于"

 when(mockStatusCalculatorService.calculateStatus(Arrays.asList(IN_PROGRESS, ABANDONNED,EXPIRED))).thenReturn(ConsolidatedStatus.EXPIRED);
Run Code Online (Sandbox Code Playgroud)

就我而言,要匹配的元素顺序无关紧要.那么在配置我的模拟时如何指定呢?

shi*_*njw 7

为新版本的Mockito和Java 8添加答案

when(
   mock.method(argThat(t -> t.containsAll(Arrays.asList(IN_PROGRESS, ABANDONED, EXPIRED))))
).thenReturn(myValue);
Run Code Online (Sandbox Code Playgroud)

  • 使用“containsAll”会产生误报,因为它还会匹配具有所需值和其他值的值。所以它与“等于,忽略顺序”不同。 (2认同)

Daw*_*ica 6

这是一个单行.使用Hamcrest containsInAnyOrder匹配器.

when(myMock.myMethod(argThat(containsInAnyOrder(IN_PROGRESS, ABANDONED, EXPIRED))))
    .thenReturn(myValue);
Run Code Online (Sandbox Code Playgroud)

  • 是的,你是对的......不过需要注意的一件事是,在大多数情况下,通过该方法将 argThat 的输出转换为预期类型似乎是强制性的 (3认同)
  • `argThat` 需要 `ArgumentMatcher`,但是 'containsInAnyOrder' 返回 `Matcher`,所以这不起作用 (2认同)