在没有 ArgumentCaptor 的情况下匹配可变对象

Den*_*kin 6 java testing junit hamcrest mockito

我必须测试一个使用可变对象的方法

private final List<LogMessage> buffer;
...
flushBuffer() {
  sender.send(buffer);
  buffer.clear();
}
Run Code Online (Sandbox Code Playgroud)

我需要测试它是否发送具有确切大小的缓冲区。
ArgumentCaptor不适用,因为捕获的集合在断言时已清除。

是否有一种匹配器可以重用 HamcresthasSize()并在方法调用时进行正确检查?

我更喜欢这样的假设collectionWhich匹配器:

bufferedSender.flushBuffer();
verify(sender).send(collectionWhich(hasSize(5)));
Run Code Online (Sandbox Code Playgroud)

Jef*_*ica 5

David 想法的一个轻量级替代方案:使用 anAnswer在通话时制作副本。未经测试的代码,但这应该非常接近:

final List<LogMessage> capturedList = new ArrayList<>();
// This uses a lambda, but you could also do it with an anonymous inner class:
// new Answer<Void>() {
//   @Override public Void answer(InvocationOnMock invocation) { /* ... */ }
// }
when(sender.send(any())).thenAnswer(invocation -> {
  List<LogMessage> argument = (List<LogMessage>) invocation.getArguments()[0];
  capturedList.addAll(argument);
});
bufferedSender.flushBuffer();
assertThat(capturedList).hasSize(5);
Run Code Online (Sandbox Code Playgroud)