Spring:是否可以在用@Transactional 注释的测试中测试事务回滚?

问题描述

我的集成测试用 @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() 对象。