Created
December 22, 2020 19:02
-
-
Save ttddyy/8bf8bc0ba49b75dbdb122973cfa6ec7f to your computer and use it in GitHub Desktop.
Class level rollback TestExecutionListener
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.example; | |
import javax.sql.DataSource; | |
import com.example.TransactionTest.MyTestExecutionListener; | |
import lombok.Data; | |
import lombok.extern.slf4j.Slf4j; | |
import org.junit.jupiter.api.MethodOrderer.OrderAnnotation; | |
import org.junit.jupiter.api.Order; | |
import org.junit.jupiter.api.Test; | |
import org.junit.jupiter.api.TestMethodOrder; | |
import org.springframework.beans.factory.DisposableBean; | |
import org.springframework.beans.factory.InitializingBean; | |
import org.springframework.beans.factory.annotation.Autowired; | |
import org.springframework.context.annotation.Bean; | |
import org.springframework.context.annotation.Configuration; | |
import org.springframework.core.NamedInheritableThreadLocal; | |
import org.springframework.jdbc.core.JdbcTemplate; | |
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; | |
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; | |
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; | |
import org.springframework.jdbc.support.JdbcTransactionManager; | |
import org.springframework.test.context.TestContext; | |
import org.springframework.test.context.TestExecutionListeners; | |
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig; | |
import org.springframework.test.context.support.AbstractTestExecutionListener; | |
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener; | |
import org.springframework.test.context.transaction.TestContextTransactionUtils; | |
import org.springframework.test.jdbc.JdbcTestUtils; | |
import org.springframework.transaction.PlatformTransactionManager; | |
import org.springframework.transaction.TransactionDefinition; | |
import org.springframework.transaction.TransactionStatus; | |
import org.springframework.transaction.annotation.EnableTransactionManagement; | |
import org.springframework.transaction.support.DefaultTransactionDefinition; | |
import static org.assertj.core.api.Assertions.assertThat; | |
/** | |
* | |
* @author Tadaya Tsuyukubo | |
*/ | |
@SpringJUnitConfig() | |
@TestMethodOrder(OrderAnnotation.class) | |
//@Transactional | |
//@TestExecutionListeners(listeners = MyTestExecutionListener.class, mergeMode = MergeMode.MERGE_WITH_DEFAULTS) | |
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, MyTestExecutionListener.class }) | |
//@TestInstance(Lifecycle.PER_CLASS) | |
class TransactionTest { | |
@Autowired | |
JdbcTemplate jdbcTemplate; | |
@Test | |
@Order(1) | |
void first() { | |
System.out.println("Running first test"); | |
this.jdbcTemplate.execute("INSERT INTO students VALUES (1, 'FOO')"); | |
int count = JdbcTestUtils.countRowsInTable(jdbcTemplate, "students"); | |
assertThat(count).isEqualTo(1); | |
} | |
@Test | |
@Order(2) | |
void second() { | |
System.out.println("Running second test"); | |
int count = JdbcTestUtils.countRowsInTable(jdbcTemplate, "students"); | |
assertThat(count).isEqualTo(1); | |
} | |
@Slf4j | |
static class MyTestExecutionListener extends AbstractTestExecutionListener { | |
private static final ThreadLocal<MyTransactionContext> currentTransactionContext = | |
new NamedInheritableThreadLocal<>("Test Transaction Context"); | |
@Override | |
public void beforeTestClass(TestContext testContext) throws Exception { | |
log.info("Start Transaction - beforeTestClass"); | |
PlatformTransactionManager tm = TestContextTransactionUtils.retrieveTransactionManager(testContext, null); | |
TransactionDefinition txDefinition = new DefaultTransactionDefinition(); | |
TransactionStatus txStatus = tm.getTransaction(txDefinition); | |
MyTransactionContext txContext = new MyTransactionContext(testContext, txDefinition, txStatus, tm); | |
MyTestExecutionListener.currentTransactionContext.set(txContext); | |
} | |
@Override | |
public void afterTestClass(TestContext testContext) throws Exception { | |
log.info("Rollback Transaction - afterTestClass"); | |
MyTransactionContext txContext = MyTestExecutionListener.currentTransactionContext.get(); | |
txContext.getTransactionManager().rollback(txContext.getTxStatus()); | |
} | |
@Data | |
static class MyTransactionContext { | |
private final TestContext testContext; | |
private final TransactionDefinition transactionDefinition; | |
private final TransactionStatus txStatus; | |
private final PlatformTransactionManager transactionManager; | |
} | |
} | |
@Configuration(proxyBeanMethods = false) | |
@EnableTransactionManagement | |
static class MyConfig { | |
@Bean | |
PlatformTransactionManager txManager(DataSource dataSource) { | |
return new JdbcTransactionManager(dataSource); | |
} | |
@Bean | |
JdbcTemplate jdbcTemplate(DataSource dataSource) { | |
return new JdbcTemplate(dataSource); | |
} | |
@Bean | |
InitializingBean populator(JdbcTemplate jdbcTemplate) { | |
return () -> jdbcTemplate.execute("CREATE TABLE students (id int, name varchar(20))"); | |
} | |
@Bean | |
EmbeddedDatabase dataSource() { | |
return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.H2).build(); | |
} | |
@Bean | |
DisposableBean cleanup(EmbeddedDatabase ds) { | |
return ds::shutdown; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment