用 mockito 测试周围的 try catch 方法
Testing surrounding try catch method with mockito
我正在弄清楚如何测试此方法并强制引发异常“DataAccessResourceFailureException”,但我没有有效的方法来做到这一点。
我需要在“ProductRepositoryImpl”class 中强制执行该异常。有什么想法吗?
ProductRepositoryImpl
@Override
public Product saveProduct(Product input) {
try {
return productRepositoryAdapter.saveProduct(input);
} catch (DataAccessResourceFailureException e) {
logger.error(ERROR_WHEN_SAVING_PRODUCT_DATA_DETAIL + e.getMessage());
}
return null;
}
ProductRepositoryAdapter
public Product saveProduct(Product input) throws DataAccessResourceFailureException {
ProductData productData = UtilTransform.productToProductData(input);
// This method throws exception when there's no connection
Product createdProduct = productDataRepository.findSkuByCountry(input.getSku(),
input.getCountry());
if (createdProduct == null) {
return Product.fromModel(productDataRepository.save(productData));
} else {
logger.error(THE_PRODUCT_ALREADY_EXISTS_IN_THE_RECORDS);
}
return null;
}
产品数据存储库
public interface ProductDataRepository extends MongoRepository<ProductData, String> {
@Query("{'sku': ?0, 'country': ?1}")
public Product findSkuByCountry(String sku, String country);
public Optional<ProductData> findById(ProductId id);
}
还有我的测试,我使用的是 mockito。
@Test
void saveProductException() {
Mockito.when(productRepository.saveProduct(buildProduct())).thenReturn(buildProduct());
Mockito.when(adapter.saveProduct(buildProduct())).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(buildProduct()));
}
错误:
org.opentest4j.AssertionFailedError: Expected org.springframework.dao.DataAccessResourceFailureException to be thrown, but nothing was thrown.
编辑。
我稍微改变了我的方法,使用这段代码(感谢大家)我能够抛出异常,所以我的代码将 return 为空。在检查我的 jacoco index.html 之后,我可以看到它成功覆盖了“异常”。
@Test
void saveProductException() {
Product product = buildProduct();
Mockito.when(adapter.saveProduct(product)).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertNull(productRepository.saveProduct(product));
}
这似乎很可疑:
Mockito.when( productRepository.saveProduct(buildProduct()) ).thenReturn(buildProduct());
. . .
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(buildProduct()) );
你是说,当 productRepository.saveProduct(buildProduct())
被调用时 return buildProduct()
但是你断言当它被调用时它应该抛出 DataAccessResourceFailureException
?
也许试试这个:
@Test
void saveProductException() {
// as NicoVanBelle recommends, ensure you're referencing the same product throughout this test
Product product = buildProduct();
Mockito.when(adapter.saveProduct(product).thenThrow(DataAccessResourceFailureException.class);
// Also as NicoVanBelle points out, when your `adapter` throws, `saveProduct` will return `null`
Assertions.assertThat(productRepository.saveProduct(product)).isNull();
}
我怀疑这里有两件事
- 您已将
productRepository.saveProduct
设置为不抛出异常,然后断言它抛出异常
Assertions.assertThrows(DataAccessResourceFailureException.class, () -> productRepository.saveProduct(buildProduct()));
- 你正在调用
buildProduct()
,我假设 returns 是新产品,但 mockito 试图检查参数相等性,所以将其作为 Product myProduct = buildProduct()
取出并使用 myProduct
@Test
void saveProductException() {
Product myProduct = buildProduct();
Mockito.when(productRepository.saveProduct(myProduct))
.thenThrow(DataAccessResourceFailureException.class);;
Mockito.when(adapter.saveProduct(buildProduct())).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(myProduct));
}
我正在弄清楚如何测试此方法并强制引发异常“DataAccessResourceFailureException”,但我没有有效的方法来做到这一点。
我需要在“ProductRepositoryImpl”class 中强制执行该异常。有什么想法吗?
ProductRepositoryImpl
@Override
public Product saveProduct(Product input) {
try {
return productRepositoryAdapter.saveProduct(input);
} catch (DataAccessResourceFailureException e) {
logger.error(ERROR_WHEN_SAVING_PRODUCT_DATA_DETAIL + e.getMessage());
}
return null;
}
ProductRepositoryAdapter
public Product saveProduct(Product input) throws DataAccessResourceFailureException {
ProductData productData = UtilTransform.productToProductData(input);
// This method throws exception when there's no connection
Product createdProduct = productDataRepository.findSkuByCountry(input.getSku(),
input.getCountry());
if (createdProduct == null) {
return Product.fromModel(productDataRepository.save(productData));
} else {
logger.error(THE_PRODUCT_ALREADY_EXISTS_IN_THE_RECORDS);
}
return null;
}
产品数据存储库
public interface ProductDataRepository extends MongoRepository<ProductData, String> {
@Query("{'sku': ?0, 'country': ?1}")
public Product findSkuByCountry(String sku, String country);
public Optional<ProductData> findById(ProductId id);
}
还有我的测试,我使用的是 mockito。
@Test
void saveProductException() {
Mockito.when(productRepository.saveProduct(buildProduct())).thenReturn(buildProduct());
Mockito.when(adapter.saveProduct(buildProduct())).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(buildProduct()));
}
错误:
org.opentest4j.AssertionFailedError: Expected org.springframework.dao.DataAccessResourceFailureException to be thrown, but nothing was thrown.
编辑。
我稍微改变了我的方法,使用这段代码(感谢大家)我能够抛出异常,所以我的代码将 return 为空。在检查我的 jacoco index.html 之后,我可以看到它成功覆盖了“异常”。
@Test
void saveProductException() {
Product product = buildProduct();
Mockito.when(adapter.saveProduct(product)).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertNull(productRepository.saveProduct(product));
}
这似乎很可疑:
Mockito.when( productRepository.saveProduct(buildProduct()) ).thenReturn(buildProduct());
. . .
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(buildProduct()) );
你是说,当 productRepository.saveProduct(buildProduct())
被调用时 return buildProduct()
但是你断言当它被调用时它应该抛出 DataAccessResourceFailureException
?
也许试试这个:
@Test
void saveProductException() {
// as NicoVanBelle recommends, ensure you're referencing the same product throughout this test
Product product = buildProduct();
Mockito.when(adapter.saveProduct(product).thenThrow(DataAccessResourceFailureException.class);
// Also as NicoVanBelle points out, when your `adapter` throws, `saveProduct` will return `null`
Assertions.assertThat(productRepository.saveProduct(product)).isNull();
}
我怀疑这里有两件事
- 您已将
productRepository.saveProduct
设置为不抛出异常,然后断言它抛出异常
Assertions.assertThrows(DataAccessResourceFailureException.class, () -> productRepository.saveProduct(buildProduct()));
- 你正在调用
buildProduct()
,我假设 returns 是新产品,但 mockito 试图检查参数相等性,所以将其作为Product myProduct = buildProduct()
取出并使用myProduct
@Test
void saveProductException() {
Product myProduct = buildProduct();
Mockito.when(productRepository.saveProduct(myProduct))
.thenThrow(DataAccessResourceFailureException.class);;
Mockito.when(adapter.saveProduct(buildProduct())).
thenThrow(DataAccessResourceFailureException.class);
Assertions.assertThrows(DataAccessResourceFailureException.class,
() -> productRepository.saveProduct(myProduct));
}