I'm running a simple JUnit test agains an application DAO. The problem is that I always get:
javax.persistence.RollbackException: Transaction marked as rollbackOnly
The JUnit test is:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = false)
@Transactional
public class PerformanceTest {
@Test
@Transactional(propagation= Propagation.REQUIRES_NEW)
@Rollback(false)
public void testMsisdnCreationPerformance() {
// Create a JPA entity
// Persist JPA entity
}
}
As you can see I'm declaring clearly not to rollback this method.
Does Spring JUnit support always sets rollback to true?
Thanks in advance,
It should work, like you expect it, but may be you open another transaction within your class under test or you have an other feature/or bug somewhere.
Btw this annotations should be enougth:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:com/my/app/context.xml"}
@Transactional
public class PerformanceTest {
@Test
@Rollback(false)
public void testMsisdnCreationPerformance() {
// Create a JPA entity
// Persist JPA entity
}
}
@See Spring Reference Chapter 9.3.5.4 Transaction management
It is strange to desire a test that changes your database and keep the modification. Tests are supposed to be orthogonal : no test depends on an other. Moreover, tests are supposed to be independent of tests order, and even idempotent.
So either you want to change you data base in your setUp()
method and rollback the change in your tearDown()
method, either you want to setup a test database with some good values in it for tests.
Maybe I am missing something here but usually you should not want that.
Just add annotation Rollback and set the flag to false.
@Test
@Rollback(false)
From official Documentation:
By default, test transactions will be automatically rolled back after completion of the test; however, transactional commit and rollback behavior can be configured declaratively via the @Commit and @Rollback annotations
@Commit indicates that the transaction for a transactional test method should be committed after the test method has completed. @Commit can be used as a direct replacement for @Rollback(false) in order to more explicitly convey the intent of the code.
I agree the Ralph's answer.
The Propagation.REQUIRES_NEW creates a new transaction and this probably does not match with the main transactional route in which the test is running.
In my simple experience the annotation @Transactional will properly work to define the transactional context in which every single test should run, delegating to this one the specific current Rollback clause (as shown by Ralph).
The Ralph's answer is useful and in the same time the Snicolas's answer concerns a particular case of managing context of tests. The idempotence is fundamental for integration and automatic tests, but should be different ways to implements them. The question is, which kind of methods do you have? And what behavior do theese methods have?
[...]
@Transactional
public class Test {
@Test
@Rollback(false)
public void test() {
[...]
Is the simple, question-coherent way :)
I use Junit5, both commit and rollback(false) works with me.
@ExtendWith(SpringExtension.class)
@SpringBootTest
@Transactional
public class MyIntegrationTest {
@Test
@DisplayName("Spring Boot Will Rollback Data, " +
"Can Disable it By Add @Commit Or @Rollback(false) Annotation")
//@Commit
//@Rollback(false)
public void test() throws Exception {
//your test codes here...
}
来源:https://stackoverflow.com/questions/9817388/junit-tests-always-rollback-the-transactions