JUnit tests always rollback transactions

I am running a simple JUnit test against a DAO application. The problem is, I always get:

javax.persistence.RollbackException: Transaction marked as rollbackOnly

      

JUnit test:

@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 am clearly stating that there is no need to rollback this method.

Does Spring JUnit support always set rollback to true?

+26


source to share


6 answers


It should work as you expect, but maybe you are opening another transaction in the class under test, or you have another function / or error somewhere.

Btw these 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 Link Chapter 9.3.5.4 Transaction Management

+51


source


It's weird to want a test that changes your database and saves the changes. Tests should be orthogonal: no test depends on another. Moreover, tests should be independent of the test order and even idempotent .

So, either you want to change your database in your method setUp()

, or revert your method change tearDown()

, or you want to set up a test database with some good values ​​in it for tests.



I may have missed something, but usually you don't need to.

+11


source


Just add the Rollback annotation and set the flag to false.

   @Test
   @Rollback(false)

      

+11


source


From the official documentation:

By default, test transactions will automatically rollback after the test ends; however transactional commit and rollback behavior can be configured declaratively via @Commit and @Rollback annotations

https://docs.spring.io/spring/docs/current/spring-framework-reference/html/integration-testing.html#integration-testing-annotations

@Commit indicates that a transaction for a transactional test method should be committed after the test method is completed. @Commit can be used as a direct replacement for @Rollback (false) to more explicitly convey the intent of the code.

+3


source


I agree with Ralph's answer.

Propagation.REQUIRES_NEW creates a new transaction and this is probably not the main transactional route in which testing is done.

In my simple experience, the @Transactional annotation will work correctly to define the transactional context in which each individual test should run, delegating to that particular current Rollback clause (as shown by Ralph).

Ralph's answer is helpful, and at the same time, Snicolas's answer deals with the specific case of test context management. idempotence is fundamental to integration and automated tests, but there should be different ways to implement them. The question is, what methods do you have? And what behavior do these methods have?

   [...]
   @Transactional

   public class Test {

   @Test
   @Rollback(false)
   public void test() {

   [...]

      

Is a simple, interrogative-sequential way :)

0


source


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...
      }

      

0


source







All Articles