我在FooService
中有一个服务方法
public void doSomething(){
ArrayList<Foo> fooList = ...;
barService.batchAddFoos(fooList);
List<String> codeList = new ArrayList<>();
for (Foo foo : fooList) {
codeList.add(foo.getCode());
}
String key = "foo_codes";
redisService.sadd(key,codeList.toArray(new String[]{}));
// other code also need use code
}
BarService.batchAddFoos
for (Foo foo : foos) {
foo.setCode(UUID.randomUUID().toString()); // dynamically generate the code value
}
然后我有一个单元测试来测试FooService逻辑
@Test
public void doSomething() throws Exception {
fooService.doSomething();
ArgumentCaptor<List<Foo>> fooListCaptor = ArgumentCaptor.forClass(List.class);
verify(barService).batchAddFoos(fooListCaptor.capture());
List<Foo> fooList = fooListCaptor.getValue();
Assert.assertNotNull(fooList.get(0).getCode()); // check code value is generated successfully
List<String> codeList = new ArrayList<>();
for (Foo foo : fooList) {
codeList.add(foo.getCode());
}
verify(redisService).sadd("foo_codes",codeList.toArray(new String[]{}));
}
但是它失败了,因为code
值是空的,实际上它不执行BarService.batchAddFoos
中的任何代码。我甚至试图显式地填充代码值,
fooList.get(0).setCode("aaa");
fooList.get(1).setCode("bbb");
但仍然失败
Argument(s) are different! Wanted:
redisService.sadd("foo_codes", "aaa", "bbb");
Actual invocation has different arguments:
redisService.sadd("foo_codes", null, null);
有什么办法可以解决这个问题吗? 由于傻瓜是FooService的一个局部变量。doSomething,您不能从测试中填充它。如果断言如下,测试将不会失败:
Mockito.verify(barService).batchAddFoos(fooListCaptor.capture());
List<Foo> fooList = fooListCaptor.getValue();
//Assert.assertNotNull(fooList.get(0).getCode());
Assert.assertFalse(fooList.isEmpty());
...
如果要在Foo构造函数中用 string初始化代码。空或任何其他非null值,您的原始断言将工作。
在这种情况下,可以根据需要填充一些对象参数的一些属性,例如
doAnswer(new Answer() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
List<Foo> fooList = invocationOnMock.getArgumentAt(0, List.class);
fooList.get(0).setCode("aaa"); // explicitly specify the first foo object have code of "aaa"
fooList.get(1).setCode("bbb"); // explicitly specify the second foo object have code of "bbb"
return null;
}
}).when(barService).batchAddFoos(anyList());