尽管存在`@Transactional`,为什么不回滚这些数据库修改?

问题描述 投票:2回答:1

为qazxsw poi写了一个简短的便利扩展:

Testcontainers

现在想测试一下。

  • Flyway载入30个条目。这些应该在fun JdbcDatabaseContainer<*>.execute(query:DSLContext.()-> Query){ val connection = DriverManager.getConnection(this.getJdbcUrl(),this.getUsername(),this.getPassword()) val create = DSL.using(connection) create.query().execute() } 中可见
  • allDataPresent插入一个没有扩展名的条目
  • canInsert也通过扩展功能做同样的事情
  • canInsertWithExtension完全按照其名称暗示并插入另外5个

除了insertMultipleWithExtension测试用例之外的所有测试用例(因为那个是只读的)都是带注释的allDataPresent

因此,我希望在测试方法之后回滚这些修改。

相反的是

@Transactional

每个[ERROR] Failures: [ERROR] InitDataIT.allDataPresent:70 Expecting: <36> to be equal to: <30> but was not. [ERROR] InitDataIT.canInsert:90 Expecting: <6> to be equal to: <1> but was not. [ERROR] InitDataIT.canInsertWithExtension:112 Expecting: <6> to be equal to: <1> but was not. 都可以自行运行。所以问题必须在于@Test

那为什么呢?更重要的是,我如何获得回滚?

完整的测试用例(也尝试注释类,没有任何区别):

@Transactional
spring-boot junit integration-testing jooq testcontainers
1个回答
2
投票

Spring @Testcontainers @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @ContextConfiguration(initializers = [InitDataIT.TestContextInitializer::class]) @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) open class InitDataIT { companion object { @JvmStatic @Container private val dbContainer = MySQLContainer<Nothing>().apply { withDatabaseName("test") withUsername("root") withPassword("") } } object TestContextInitializer: ApplicationContextInitializer<ConfigurableApplicationContext> { override fun initialize(applicationContext: ConfigurableApplicationContext) { TestPropertyValues.of( "spring.datasource.url=${dbContainer.jdbcUrl}", "spring.datasource.username=${dbContainer.username}", "spring.datasource.password=${dbContainer.password}", "spring.datasource.driver-class-name=${dbContainer.driverClassName}" ).applyTo(applicationContext) } } private val create:DSLContext @Autowired constructor(create:DSLContext){ this.create = create } @Test fun allDataPresent(){ //given val expectedNumberOfEntries = 30 val query = create.selectCount() .from(CUSTOMERS) //when val numberOfEntries = query.fetchOne{it.value1()} //then Assertions.assertThat(numberOfEntries).isEqualTo(expectedNumberOfEntries) } @Test @Transactional open fun canInsert(){ //given val insertquery = create.insertInto(CUSTOMERS) .columns(CUSTOMERS.FIRSTNAME,CUSTOMERS.LASTNAME,CUSTOMERS.EMAIL, CUSTOMERS.STATUS) .values("Alice","Tester","[email protected]",CustomerStatus.Contacted.name) val expectedNumberInOffice2 = 1 //when insertquery.execute() //then val numberInOffice2 = create.selectCount() .from(CUSTOMERS) .where(CUSTOMERS.EMAIL.contains("somewhere")) .fetchOne{it.value1()} assertThat(numberInOffice2).isEqualTo(expectedNumberInOffice2) } @Test @Transactional open fun canInsertWithExtension(){ //given dbContainer.execute { insertInto(CUSTOMERS) .columns(CUSTOMERS.FIRSTNAME,CUSTOMERS.LASTNAME,CUSTOMERS.EMAIL, CUSTOMERS.STATUS) .values("Alice","Tester","[email protected]",CustomerStatus.Contacted.name) } val expectedNumberInOffice2 = 1 //when val numberInOffice2 = create.selectCount() .from(CUSTOMERS) .where(CUSTOMERS.EMAIL.contains("somewhere")) .fetchOne{it.value1()} //then assertThat(numberInOffice2).isEqualTo(expectedNumberInOffice2) } @Test @Transactional open fun insertMultipleWithExtension(){ //given dbContainer.execute { insertInto(CUSTOMERS) .columns(CUSTOMERS.FIRSTNAME,CUSTOMERS.LASTNAME,CUSTOMERS.EMAIL, CUSTOMERS.STATUS) .values("Alice","Make","[email protected]", CustomerStatus.Customer.name) .values("Bob","Another","[email protected]", CustomerStatus.ClosedLost.name) .values("Charlie","Integration","[email protected]",CustomerStatus.NotContacted.name) .values("Denise","Test","[email protected]",CustomerStatus.Customer.name) .values("Ellie","Now","[email protected]",CustomerStatus.Contacted.name) } val expectedNumberInOffice2 = 5 //when val numberInOffice2 = create.selectCount() .from(CUSTOMERS) .where(CUSTOMERS.EMAIL.contains("somewhere")) .fetchOne{it.value1()} //then assertThat(numberInOffice2).isEqualTo(expectedNumberInOffice2) } } 注释不仅与你的@Transactional创建的JDBC连接神奇地起作用。您的DriverManager对象应该在您的Spring托管数据源上运行。

© www.soinside.com 2019 - 2024. All rights reserved.