我试图使用Mockito的ArgumentCapture
来检索使用的泛型参数,但是在我的方法中使用相同的基本类型,但使用不同的泛型参数两次。
为了简化示例,我编写了一个与我的代码不同但具有相同问题的测试:
@Captor private ArgumentCaptor<ArrayList<String>> stringl;
@Captor private ArgumentCaptor<ArrayList<Boolean>> booleanl;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
} //setup
@Test
public void test()
{
Foo foo = mock(Foo.class);
List<String> stringList = new ArrayList<String>();
List<Boolean> booleanList = new ArrayList<Boolean>();
foo.doSomething(stringList);
foo.doSomething(booleanList);
verify(foo).doSomething(stringl.capture());
verify(foo).doSomething(booleanl.capture());
} //test
private static class Foo
{
public <T> void doSomething(List<T> list){}
}
执行测试会产生以下错误:
org.mockito.exceptions.verification.TooManyActualInvocations:
foo.doSomething(<Capturing argument>);
Wanted 1 time:
-> at test(Test.java:19)
But was 2 times. Undesired invocation:
-> at test(Test.java:21)
为了查看发生了什么,我将times(2)
添加到验证方法中,然后检查参数捕获。两者都选择了第二次调用,这意味着我永远无法捕获类型为List<String>
的第一个参数。
是否有一种方法可以让ArgumentCapture
识别相同基型的不同泛型,即区分List<Boolean>
和List<String>
?
欢呼,阿列克谢蓝色
我的修改是:
@Captor private ArgumentCaptor<ArrayList<?>> aList;
@Before
public void setup()
{
MockitoAnnotations.initMocks(this);
} //setup
@Test
public void test()
{
Foo foo = mock(Foo.class);
String testString = "Hello Test";
Boolean testBoolean = true;
List<String> stringList = new ArrayList<String>();
stringList.add(testString);
List<Boolean> booleanList = new ArrayList<Boolean>();
booleanList = testBoolean;
foo.doSomething(stringList);
foo.doSomething(booleanList);
//verify to capture and assertion that it happened twice
verify(foo, times(2)).doSomething(aList.capture());
//Get all captured values from the verified invocation
List<ArrayList<?>> args aList.getAllValues();
//verify first list, should be String
assertEquals("TestString assertion wrong", testString, args.get(0).get(0));
//verify second list, should be Boolean
assertEquals("TestBoolean assertion wrong", testBoolean, args.get(1).get(0));
} //test
private static class Foo
{
public <T> void doSomething(List<T> list){}
}
不使用现有的ArgumentCaptor
类。由于类型擦除,该信息将丢失。我建议您使用单个捕获器,并在所有调用中获取传递的参数。然后,您可以验证第一次使用List<String>
调用了它,第二次使用List<Boolean>
调用了它。当然,您可以通过验证list的内容来做到这一点。
另一种选择是注入ArgumentCaptor
@Captor
private ArgumentCaptor<List<Person>> argumentCaptor;
http://blog.jdriven.com/2012/10/mockito-using-argumentcaptor-for-generic-typed-collections/对我来说,我试图抛出相同的错误按摩两次。
如果你试图验证相同的按摩,那么你必须使用import static org.mockito.Mockito.times
的"times"方法;
verify(anyFakeObject,times(num)).method(parmeter);
其中numb为同一次按摩的计数。