如何用mockito捕获特定types的列表
有没有办法使用mockitos ArgumentCaptore捕获特定types的列表。 这不起作用:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
使用@Captor批注可以避免嵌套的generics问题:
@RunWith(MockitoJUnitRunner.class) public class Test{ @Mock private Service service; @Captor private ArgumentCaptor<ArrayList<SomeType>> captor; @Test public void shouldDoStuffWithListValues() { //... verify(service).doStuff(captor.capture())); } }
是的,这是一个普遍的generics问题,不是mockito特定的。
ArrayList<SomeType>
没有类对象,因此您无法安全地将此类对象传递给需要Class<ArrayList<SomeType>>
。
您可以将对象转换为正确的types:
Class<ArrayList<SomeType>> listClass = (Class<ArrayList<SomeType>>)(Class)ArrayList.class; ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(listClass);
这将给出一些关于不安全转换的警告,当然你的ArgumentCaptor也不能真正区分ArrayList<SomeType>
和ArrayList<AnotherType>
而不检查元素。
(正如在另一个答案中提到的那样,虽然这是一个generics的问题,但是对于types安全问题,使用@Captor
注解来解决Mockito特定的问题,仍然无法区分ArrayList<SomeType>
和ArrayList<OtherType>
。)
编辑:
再看看tenshi的评论。 您可以将PaŭloEbermann的原始代码更改为(更简单)
final ArgumentCaptor<List<SomeType>> listCaptor = ArgumentCaptor.forClass((Class) List.class);
如果你不害怕旧的Java风格(非types安全通用)语义,这也可以工作,并且相当简单(r):
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class); List<SomeType> list = argument.getValue(); // first captured List, etc.
List<String> mockedList = mock(List.class); List<String> l = new ArrayList(); l.add("someElement"); mockedList.addAll(l); ArgumentCaptor<List> argumentCaptor = ArgumentCaptor.forClass(List.class); verify(mockedList).addAll(argumentCaptor.capture()); List<String> capturedArgument = argumentCaptor.<List<String>>getValue(); assertThat(capturedArgument, hasItem("someElement"));
我在Android应用程序中遇到了与testing活动相同的问题。 我使用了ActivityInstrumentationTestCase2
和MockitoAnnotations.initMocks(this);
没有工作。 我分别用另外一个类来解决这个问题。 例如:
class CaptorHolder { @Captor ArgumentCaptor<Callback<AuthResponse>> captor; public CaptorHolder() { MockitoAnnotations.initMocks(this); } }
那么,在活动testing方法中:
HubstaffService hubstaffService = mock(HubstaffService.class); fragment.setHubstaffService(hubstaffService); CaptorHolder captorHolder = new CaptorHolder(); ArgumentCaptor<Callback<AuthResponse>> captor = captorHolder.captor; onView(withId(R.id.signInBtn)) .perform(click()); verify(hubstaffService).authorize(anyString(), anyString(), captor.capture()); Callback<AuthResponse> callback = captor.getValue();