And*_*rle 275 java junit unit-testing mockito
有没有办法使用mockitos ArgumentCaptore捕获特定类型的列表.这不起作用:
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(ArrayList.class);
Run Code Online (Sandbox Code Playgroud)
cru*_*dog 491
使用@Captor注释可以避免嵌套的泛型问题:
public class Test{
@Mock
private Service service;
@Captor
private ArgumentCaptor<ArrayList<SomeType>> captor;
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void shouldDoStuffWithListValues() {
//...
verify(service).doStuff(captor.capture()));
}
}
Run Code Online (Sandbox Code Playgroud)
Paŭ*_*ann 133
是的,这是一个普遍的泛型问题,而不是特定于mockito的问题.
没有类对象ArrayList<SomeType>,因此您无法将此类对象类型安全地传递给需要的方法Class<ArrayList<SomeType>>.
您可以将对象强制转换为正确的类型:
Class<ArrayList<SomeType>> listClass =
(Class<ArrayList<SomeType>>)(Class)ArrayList.class;
ArgumentCaptor<ArrayList<SomeType>> argument = ArgumentCaptor.forClass(listClass);
Run Code Online (Sandbox Code Playgroud)
这将给出一些关于不安全的强制转换的警告,当然你的ArgumentCaptor无法区分ArrayList<SomeType>和ArrayList<AnotherType>不检查元素.
(正如在另一个答案中所提到的,虽然这是一个普遍的泛型问题,但是对于带有@Captor注释的类型安全问题,存在Mockito特定的解决方案.它仍然无法区分an ArrayList<SomeType>和an ArrayList<OtherType>.)
另请参阅tenshi的评论.您可以将原始代码从PaŭloEbermann更改为此(更简单)
final ArgumentCaptor<List<SomeType>> listCaptor
= ArgumentCaptor.forClass((Class) List.class);
Run Code Online (Sandbox Code Playgroud)
rog*_*ack 14
如果你不害怕旧的java风格(非类型安全通用)语义,这也有效并且相当简单:
ArgumentCaptor<List> argument = ArgumentCaptor.forClass(List.class);
verify(subject.method(argument.capture()); // run your code
List<SomeType> list = argument.getValue(); // first captured List, etc.
Run Code Online (Sandbox Code Playgroud)
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"));
Run Code Online (Sandbox Code Playgroud)
根据@tenshi 和@pkalinow 的评论(也对@rogerdpack 表示敬意),以下是创建列表参数捕获器的简单解决方案,该解决方案还禁用了“使用未经检查或不安全的操作”警告:
@SuppressWarnings("unchecked")
final ArgumentCaptor<List<SomeType>> someTypeListArgumentCaptor =
ArgumentCaptor.forClass(List.class);
Run Code Online (Sandbox Code Playgroud)
我们的团队在我们的单元测试中已经使用了一段时间,这对我们来说似乎是最直接的解决方案。