mockito 无法在Java单元测试中捕获值

ddrv8njm  于 2022-11-08  发布在  Java
关注(0)|答案(2)|浏览(212)

我有以下服务方法:

public CommandDTO update(UUID uuid, EmployeeRequest request) {
    final List<Product> productList = productRepository
            .findAllByUuidOrderByOrderNumber(uuid); 

    final List<UUID> uuidList = request.getUuidList();

    for (int i = 0; i < uuidList.size(); i++) {        
        Product product = productList.get(i);
        product.setOrderNumber(i + 1);

        // how can I get the product value in this line? 
    }

    return CommandDTO.builder().uuid(uuid).build();
}

通常,我使用ArgumentCaptor来获取传递给仓库或服务的值。然而,在这个例子中,我想在product.setOrderNumber(i + 1);之后获取的产品值不是传递给服务或仓库的。因此,我无法获取它。我不确定使用@SpydoAnswer是否可行,但据我所知,这些方法不能使用,因为值没有传递给服务或存储库。2有什么想法吗?

z3yyvxxp

z3yyvxxp1#

您可以模拟存储库以返回模拟的列表:

public test() {

    Product product1 = mock(Product.class);
    Product product2 = mock(Product.class);
    List list = Arraylist();
    list.add(product1);
    list.add(product2);

    when(productRepositoryMock.findAllByUuidOrderByOrderNumber(uuid))
       .thenReturn(list)
    when(product1).setOrderNumber(captor.capture)

在本例中,您可以在此处使用ArgumentCaptor,但我认为它在本例中是多余的,简单的验证调用就足够了

service.update(.....);

verify.(product1).setOrderNumber(value);
iqjalb3h

iqjalb3h2#

变量product来自productList,而productList又来自repository.findAllByUuidOrderByOrderNumber()方法,所以如果你模拟了仓库,你可以写这样的代码:

Product givenProduct = new Product();
UUID givenUUID = UUID.randomUUID();
// Create an EmployeeRequest with a `uuidList`
EmployeeRequest givenRequest = new EmployeeRequest(/* TODO */); 
// Use Mockito to return a `productList` you choose
// This uses a static import of `Mockito.when()`
when(productRepository.findAllByUuidOrderByOrderNumber(givenUUID)).thenReturn(List.of(givenProduct));
service.updateRequest(givenUUID, givenRequest);

从理论上讲,您甚至可以在上面的测试逻辑中返回一个模拟的产品,但我建议使用一个真正的Product对象。
现在,无论产品发生了什么,都可以在测试中Assert。
例如:

// `givenProduct` is element 0, and thus will get an orderNumber of 1
assertThat(givenProduct.getOrderNumber()).isEqualTo(1);

相关问题