gpt4 book ai didi

java - 使用 InOrder 验证更改的 List 对象的方法调用

转载 作者:太空宇宙 更新时间:2023-11-04 12:22:04 25 4
gpt4 key购买 nike

我有一个回调接口(interface),它有一个采用 List 的方法。目的。我想使用InOrder验证回调方法是否以正确的顺序、使用正确的参数调用了适当的次数。

问题是 Mockito 似乎很困惑,因为我传递了相同的 List对象到方法中并在调用之间修改它。当我调用InOrder.verify()时,我想验证 List 的值执行该方法调用时的对象

代码:

public class Test {
@Test
public void test() {
Callback callback = Mockito.mock(Callback.class);
InOrder inOrder = Mockito.inOrder(callback);

{
List<String> list = new ArrayList<String>(); //note: this List object is inaccessible from the unit test in my real use-case
callback.foo("name1", list);
list.add("value");
callback.foo("name2", list);
}

inOrder.verify(callback).foo("name1", Arrays.<String> asList()); //fails here
inOrder.verify(callback).foo("name2", Arrays.asList("value"));
}

interface Callback {
void foo(String name, List<String> list);
}
}

错误消息:

Argument(s) are different!  Wanted:
callback.onFoo([]);
Actual invocation has different arguments:
callback.onFoo([value]);

传递 List副本对象放入每个回调方法调用中使得测试通过。但我不想创建一个新的 List每次调用该方法时。

我查看了MockSettings您可以传递给 Mockito.mock() 的对象,但没有看到任何可能有帮助的内容。

This question和我的很相似。但该解决方案不会验证传递到每个方法调用中的集合的内容 - 它仅验证某些集合已传递到其中的事实( anyCollectionOf() )。它验证最终结果,但不验证单独的调用

This answer似乎提供了一个潜在的解决方案。它使用 ArgumentCaptor捕获传递到方法中的对象。但是当我用它来验证第一个方法调用时,它返回 List 对它进行所有修改后,因此测试失败。我需要它返回 List状态与 List 匹配的对象对象在该精确调用时的状态。

ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);

inOrder.verify(callback).foo(Mockito.eq("name1"), argument.capture());
assertEquals(Arrays.asList(), argument.getValue()); //fails: "expected: <[]> but was: <[value]>

inOrder.verify(callback).foo(Mockito.eq("name2"), argument.capture());
assertEquals(Arrays.asList("value"), argument.getValue());

如何在不牺牲任何粒度的情况下通过此测试?

最佳答案

question that @SpaceTrucker linked to提供了解决方案。

基本上,为该方法创建一个自定义Answer,并在每次调用该方法时存储List 参数的副本。然后,验证所有副本是否符合您的预期。这并不理想,但它有效。

@Test
public void test() {
Callback callback = Mockito.mock(Callback.class);

final List<List<String>> listParameters = new ArrayList<List<String>>();
Mockito.doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
List<String> list = (List<String>) invocation.getArguments()[1];
listParameters.add(new ArrayList<String>(list));
return null;
}
}).when(callback).foo(Mockito.anyString(), Mockito.anyList());

{
List<String> list = new ArrayList<String>(); //note: this List object is inaccessible from the unit test in my real use-case
callback.foo("name1", list);
list.add("value");
callback.foo("name2", list);
}

InOrder inOrder = Mockito.inOrder(callback);
inOrder.verify(callback).foo(Mockito.eq("name1"), Mockito.anyList());
inOrder.verify(callback).foo(Mockito.eq("name2"), Mockito.anyList());

Assert.assertEquals(Arrays.asList(
Arrays.asList(),
Arrays.asList("value")
), listParameters);
}

关于java - 使用 InOrder 验证更改的 List 对象的方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38779862/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com