问题描述
我的集成测试用 @Transactional
注释,这样测试数据实际上不会写入数据库。
现在我想测试一个实现的事务行为:
@Transactional
fun update(productTO: ProductTO): Product {
val product = findProduct(productTO.id).apply { price = productTO.price }
// should rollback
productPersistence.save(product)
// when this throws a RuntimeException
otherService.publishUpdate(product)
}
这是测试:
@Transactional
@Testcontainers
@SpringBoottest
class ProductTest {
@Test
fun `should rollback when sync fails`() {
val product = seedCreator.createProduct()
assertthat(product.price).isEqualTo(MonetaryAmount("5.00"))
// throw RuntimeException
Mockito.`when`(otherService.publishUpdate(any())).thenThrow(MyException())
assertThrows<MyException> {
sut.update(ProductTO(product.id,MonetaryAmount("10.00")))
}
// Verify that update was NOT applied
// Assertion fails!
assertthat(productPersistence.find(product.id))
.isNotNull()
.extracting(Product::price.name)
.containsExactly(MonetaryAmount("5.00"))
}
}
我想知道 @Transactional
本身是否可以测试 @Transactional
实现的回滚行为?
解决方法
我猜测 seedCreator.createProduct()
返回的对象与稍后测试中 productPersistence.find(product.id)
返回的对象相同。
如果您想查看当前的数据库状态,您需要使用 refresh
EntityManager.refresh()
对象。