简体   繁体   中英

Spring boot integration test rollback does not work

In spring boot I'm trying to create my first transactional test, but the trasaction doesn't work.

@TestPropertySource(locations = "classpath:test.properties")
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@RunWith(SpringJUnit4ClassRunner.class)
//@RunWith(SpringRunner.class)
@Transactional
@TestExecutionListeners(
    mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS,
    listeners = {TransactionalTestExecutionListener.class}
)
public class IntegrationTests
{
    @Autowired
    TemperatureLogRepository temperatureLogRepository;

    @Test
    @SqlGroup({
        @Sql(
            executionPhase = Sql.ExecutionPhase.BEFORE_TEST_METHOD,
            config = @SqlConfig(transactionMode = ISOLATED),
            scripts = "classpath:sqls/insertRecords2.sql"
        )
    })
    public void firstRepoTest() throws SQLException
    {
        assertThat(temperatureLogRepository.getFullList().size()).isEqualByComparingTo(0);
    }
}

I know that SqlGroup is not necessary, but there will be more files added.

That I have now:

  1. SQL file executed well and inserted to the DB.
  2. The getFullList() method can read it and returns with the right data.
  3. After the test I still have the data in the DB, there is no rollback on the transaction.

I'm not exactly sure they are running in the same transaction. Is it possible to be the data commited to the db before the getFullList() method run?

What I need:

  1. @Sql inserts data to the transaction.
  2. getFullList() read the data from the transaction.
  3. Test the returned data.
  4. Rollback the transaction.

From Spring Testing - Executing SQL scripts declaratively with @Sql :

Script execution phases

By default, SQL scripts will be executed before the corresponding test method. However, if a particular set of scripts needs to be executed after the test method — for example, to clean up database state — the executionPhase attribute in @Sql can be used as seen in the following example. Note that ISOLATED and AFTER_TEST_METHOD are statically imported from Sql.TransactionMode and Sql.ExecutionPhase respectively.

@Test 
@Sql(
    scripts = "create-test-data.sql",
    config = @SqlConfig(transactionMode = ISOLATED) ) @Sql(
    scripts = "delete-test-data.sql",
    config = @SqlConfig(transactionMode = ISOLATED),
    executionPhase = AFTER_TEST_METHOD ) 
public void userTest {
    // execute code that needs the test data to be committed
    // to the database outside of the test's transaction 
}

Related question: How to execute @Sql before a @Before method

UPDATE

Remove @SqlConfig from @Sql :

config = @SqlConfig(transactionMode = ISOLATED)

Or change to:

config = @SqlConfig(transactionMode = TransactionMode.INFERRED)

SQL script runs in separate transaction which is not roll backed:

org.springframework.test.context.jdbc.SqlConfig.TransactionMode.ISOLATED

Indicates that SQL scripts should always be executed in a new, isolated transaction that will be immediately committed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM