Open spring-projects-issues opened 15 years ago
Sam Brannen commented
Since this issue has received 0 votes in the last 6 years, I am resolving it as "Won't Fix".
However, if the community deems this issue still relevant, this issue may potentially be reassessed at a later date.
Sam Brannen commented
Reopening this issue in light of #21093 and JUnit Jupiter's upcoming support for scenario tests.
哈哈哈,nb啊铁质
Any progress? I found a workaround as below but I think this code is a bit hacky. So, I hope this feature be supported officially.
@Suppress("UnnecessaryAbstractClass", "EmptyFunctionBlock")
@ContextBootTest
@TestInstance(value = TestInstance.Lifecycle.PER_CLASS)
@Execution(ExecutionMode.SAME_THREAD)
abstract class AbstractTransactionalScenarioTest {
@Autowired(required = true)
lateinit var transactionManager: PlatformTransactionManager
lateinit var status: TransactionStatus
@BeforeAll
private fun beforeTestClass() {
val td = DefaultTransactionDefinition().apply {
setName("ScenarioTestTx_${Thread.currentThread().id}")
propagationBehavior = TransactionDefinition.PROPAGATION_REQUIRED
}
status = transactionManager.getTransaction(td)
beforeAll()
}
@AfterAll
private fun afterTestClass() {
afterAll()
transactionManager.rollback(status)
}
protected fun beforeAll() {}
protected fun afterAll() {}
}
class ScenarioTest : AbstractTransactionalScenarioTest() {
override fun beforeAll() {
// class wide init code. ex, db init
}
@Test
@Transactional(propagation = Propagation.NESTED)
fun testA() {
// test 1...
}
@Test
@Transactional(propagation = Propagation.NESTED)
fun testB() {
// test 2...
}
}
Alternatively, you can create a custom TestExecutionListener
that start/stop a transaction at the test class level.
Something like:
class MyTestExecutionListener extends AbstractTestExecutionListener {
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
PlatformTransactionManager tm = TestContextTransactionUtils.retrieveTransactionManager(testContext, null);
TransactionDefinition txDef = new DefaultTransactionDefinition();
TransactionStatus txStatus = tm.getTransaction(txDef);
// put necessary context variables to threadlocal if parallel execution is needed
....
}
@Override
public void afterTestClass(TestContext testContext) throws Exception {
// retrieve necessary context values.
....
tm.rollback(txStatus);
}
}
Existing TransactionalTestExecutionListener
is a good source for implementation details.
In addition, you can use JUnit5 @TestMethodOrder
to ensure the testing order within the test class.
@ttddyy Thank you for your reply!
But sadly, I tried your annotation style solution but it didn't work properly.
It seems rollback didn't work for each test case.
(@Transactional(propagation = Propagation.NESTED)
doesn't work?)
@junichimiyazaki I just wrote this sample impl and seems working to me. It starts and rollbacks transaction at class level. You can extend and add per method behavior if you want.
Just looking back your example, you want to add the NESTED propagation in each test method with rollback?? I'm not sure why you want to do it.
Can it be simply start/rollback transaction on each method, which is exactly what TransactionalTestExecutionListener
do by default.
@ttddyy I'm sorry, I was misunderstanding it. Your case seems to fully satisfy the requirements of this ticket.
The reason what I added the NESTED propagation is that I want to add common DB initialization per class. Because it simplifies and speeds up each test cases.
I found this solution on StackOverflow and it saved the day:
Add the @DirtiesContext annotation, but provide it with the AFTER_EACH_TEST_METHOD classMode
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
Eric Jain opened SPR-5520 and commented
Being able to configure that all test methods in a class should be run in the same transaction would be useful for people using TestNG (which supports test method dependencies) to write functional tests.
This feature could also be useful in JUnit Jupiter when using
@TestInstance(PER_CLASS)
or the planned support for scenario tests.Affects: 2.5.6
Issue Links:
21093 TestEntityManager can't be configured in
@BeforeAll
method in test class with@TestInstance
(PERCLASS) in JUnit Jupiter ("is duplicated by"_)16024 Support
@Transactional
on TestNG@BeforeClass
methods in the TestContext framework1 votes, 1 watchers