Issue
I have looked at several usage examples of e.g. Using Mockito ArgumentCaptor, but I have confused about the proper usage for the following scenario:
Here is the method that I want to test:
@Override
public ProductDTO create(Product product, UUID uuid) {
// code omitted for brevity
final Product saved = productRepository.save(product);
final Currency currency = currencyService.getCurrencyByUuid(uuid);
return new ProductDTO(saved, currency);
}
My test method:
@RunWith(MockitoJUnitRunner.class)
public class ProductServiceImplTest {
@Mock
private ProductRepository productRepository;
@Mock
private CurrencyService currencyService;
@InjectMocks
private ProductServiceImpl productService;
@Captor
private ArgumentCaptor<Product> productCaptor;
@Test
public void test_create() {
UUID uuid = UUID.fromString("00000000-0000-0000-0000-000000000001");
UUID productUuid = UUID.fromString("00000000-0000-0000-0000-000000000222");
Currency currency = Currency.getInstance("EUR");
Product product = new Product();
productCostBySite.setProductUuid(productUuid);
// 1. prepare the values
when(productRepository.save(productCaptor.capture())).thenReturn(product);
when(currencyService.getCurrencyByUuid(uuid)).thenReturn(currency);
// 2. call the service method that is tested
ProductDTO result = productService.create(product);
// 3. Check if the captured value is the expected one
Product value = productCaptor.getValue();
assertEquals(productUuid, value.getProductUuid());
assertEquals(currency.getCurrencyCode(),
result.getCurrency().getCurrencyCode());
}
}
Here are the questions (the numbers are also the comment numbers of test method):
1. I tested productRepository.save
method using ArgumentCaptor
and currencyService.getCurrencyByUuid(uuid)
by returned value as it is not a repository call. Is that true?
2. I called the service method, but in some examples verify
method is used. I am not sure if I need to use verify
method for this example? Any idea?
3. I used the returned value for service and used captured value for repository. Is that a correct approach?
Solution
Eugene is right, you don't need an ArgumentCaptor
. To answer the question of when you need it: if you want to verify the value of a transatory object you don't have access to before or after your method.
For example, in
boolean createAndSave(String productName) {
Product p = new Product(productName);
return repository.save(p);
}
you don't have access to the created Product
but want to verify it was created correctly. To do this, you can capture it:
ArgumentCaptor<Product> savedCaptor = ArgumentCaptor.forClass(Product.class);
service.createAndSave("name");
verify(repository).save(savedCaptor.capture()); // get the product being saved
Product saved = savedCaptor.getValue();
assertEqual("name", saved.getName());
Now, you make sure that the repository was used to save a product with the name you gave the service.
In your case, you can just use when(repository.save(any()).thenReturn(product)
with a product you created ahead of time.
Answered By - daniu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.