Home > OS >  Cannot catch value in Java Unit Test
Cannot catch value in Java Unit Test

Time:05-18

I have the following service method:

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();
}

Normally, I use ArgumentCaptor in order to get values passing to repository or service. Howevcer, in this example, the product value that I want to get after product.setOrderNumber(i 1); is not passing service or repository. For this reason I cannot get it. I am not sure if it would be possible using @Spy or doAnswer, but as far as I know, these methods cannot be used as the value is not passing to service or repo. Any idea?

CodePudding user response:

The product variable comes from productList, which in turn comes from the repository.findAllByUuidOrderByOrderNumber() method. So if you mocked your repository, you could write something like this:

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);

Theoretically you could even return a mocked product in the test logic above, but I suggest using a real Product object.

And now whatever happens to that product, can be asserted within your test.

For example:

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

CodePudding user response:

You can mock you repository to return list of mock's:

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) 

In this case you can use ArgumentCaptor here, but I belive it's redundant in this case, and simple verify call will be enough

service.update(.....);

verify.(product1).setOrderNumber(value);
  • Related