如何获得在模拟方法中生成的值



我在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());

相关内容

  • 没有找到相关文章

最新更新