我在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
值为null,实际上它不执行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);
有什么想法解决这个问题?
答案 0 :(得分:0)
由于 fooList 是 FooService.doSomething 的局部变量,因此无法从测试中填充它。如果断言如下,则您的测试不会失败:
Mockito.verify(barService).batchAddFoos(fooListCaptor.capture());
List<Foo> fooList = fooListCaptor.getValue();
//Assert.assertNotNull(fooList.get(0).getCode());
Assert.assertFalse(fooList.isEmpty());
...
如果您要使用 Strings.EMPTY 或任何其他非空初始化 Foo 构造函数中的代码价值,你的原始断言将起作用。
答案 1 :(得分:0)
在这种情况下,可以根据需要填充某些对象参数的某些属性,例如
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());