【问题标题】:Spring: Is it possible to test transaction rollback in a Test annotated with @Transactional?Spring:是否可以在使用@Transactional 注释的测试中测试事务回滚?
【发布时间】:2021-08-16 20:54:21
【问题描述】:

我的集成测试用@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 实现的回滚行为?

【问题讨论】:

    标签: spring jpa junit5 spring-transactions spring-boot-test


    【解决方案1】:

    我猜seedCreator.createProduct()返回的对象和productPersistence.find(product.id)稍后在测试中返回的对象是一样的。

    如果您想查看其当前的数据库状态,您需要使用EntityManager.refresh() refresh 对象。

    【讨论】:

    • productPersistence.find(product.id) 之后调用EntityManager.refresh() 并没有改变结果。澄清一下:seedCreator创建的产品价格为5.00,然后我更新到10.00,但是抛出异常,所以应该回滚更改,使价格仍然是5.00
    猜你喜欢
    • 2015-06-19
    • 1970-01-01
    • 2016-04-24
    • 2019-08-27
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2018-03-25
    • 1970-01-01
    相关资源
    最近更新 更多