为什么在存在@Transactional的情况下为何不回滚这些数据库修改?

时间:2019-04-11 14:17:37

标签: spring-boot junit integration-testing jooq testcontainers

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

现在想对其进行测试。

  • Flyway会加载30个条目。这些应该在canInsert
  • 中可见
  • canInsertWithExtension插入一个不带扩展名的条目
  • insertMultipleWithExtension一样,只是通过扩展功能
  • allDataPresent的名称完全相同,并插入另外5个

@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都能正常工作。因此问题必须出在@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","Alice.Tester@somewhere.tt",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","Alice.Tester@somewhere.tt",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","Alice.Make@somewhere.tt", CustomerStatus.Customer.name) .values("Bob","Another","Bob.Another@somewhere.tt", CustomerStatus.ClosedLost.name) .values("Charlie","Integration","Charlie.Integration@somewhere.tt",CustomerStatus.NotContacted.name) .values("Denise","Test","Denise.Test@somewhere.tt",CustomerStatus.Customer.name) .values("Ellie","Now","Ellie.Now@somewhere.tt",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) } } 上。

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

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

(\d{2}\s\d{2}\s\d{4})

1 个答案:

答案 0 :(得分:2)

Spring import { createMaterialTopTabNavigator, createStackNavigator } from 'react-navigation' import MyComponent from '../some-component-folder/' import MyHomeComponent from '../some-component-folder/' import MyNavigator from '../some-navigator-folder/' const TabNavigator = createMaterialTopTabNavigator( { Tab1: { screen: MyComponent } Tab2: { screen: MyNavigator } } ) const StackNavigator = createStackNavigator( { Screen1: { screen: MyHomeComponent } Screen2: { screen: TabNavigator } } ) 注释不仅可以神奇地与您创建的forum.txtbox.Focus JDBC连接配合使用。您的@Transactional对象应该在您的Spring托管数据源上运行。