Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

@Rollback(false) not working on @Before using SpringJUnit4ClassRunner

In a JUnit test in my Spring application, I'd like to insert a lot of data in a setup method, and then use it to test against. However, whatever is done in the @Before method appears to be rolled back after each test, even if I annotate the method with @Rollback(false)

Here's a simplified version of what I'm trying to do:

public class TestClass
{
   @Autowired 
   MyService service;

   @Before
   public void setup()
   {
      if(service.getById(1) == null)
      {
         Thing thing = new Thing();
         thing.setId(1);
         service.create(new Thing(1))
      }
   }
}

I've also tried using @BeforeClass, but that requires the method to be static, and executes before any @Autowired setter methods are called, so I can't get access to the services I need to call when @BeforeClass runs.

I tried using @PostConstruct, but there are issues with having a transaction available (and my setup is such that a Hibernate session is only available when a transaction starts). Weirdly a session seemed to be available, but two objects got from within the same session were not equal, meaning Hibernate 1st-level cache seemed to be failing, or each operation was happening in a separate session. @BeforeTransaction seemed to exhibit the same behaviour.

like image 594
EngineerBetter_DJ Avatar asked Nov 04 '22 07:11

EngineerBetter_DJ


1 Answers

The Spring TransactionalTestExecutionListener is responsible for managing the transaction for the Junit Tests. It uses two methods (beforeTestMethod and afterTestMethod) to start and end the transaction for each of the Junit Tests.

As for @Before annotation it seems to work like this, It applies the @Rollback attribute specified on the Test method to the to setUp method with @Before annotation

I have this example to explain the process, I have two test methods one with (roll back false the other with roll back true)

      @RunWith(SpringJUnit4ClassRunner.class)
      @ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes={SpringConfig.class})
      @Transactional
       public class MyTest 
      {

        @Before
        public void setUp()
        {
            //When executing this method setUp
            //The transaction will be rolled back after rollBackTrue Test
            //The transaction will not be rolled back after rollBackFalse Test
         }


        @Test
        @Rollback(true)
        public void rollBackTrue()
        {
            Assert.assertTrue(true);
        }

        @Test
        @Rollback(false)
        public void rollBackFalse()
        {
            Assert.assertTrue(true);
        }
    }
like image 149
Prasanna Talakanti Avatar answered Nov 11 '22 15:11

Prasanna Talakanti