Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 235 Vote(s) - 3.54 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to rollback a database transaction when testing services with Spring in JUnit?

#1
I have no problem testing my DAO and services, but when I test `INSERT`s or `UPDATE`s I want to rollback the transaction and not effect my database.

I'm using `@Transactional` inside my services to manage transactions. I want to know, is it possible to know if a transaction will be fine, but rollback it to prevent altering database?

This is my Test:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring.cfg.xml")
@TransactionConfiguration(defaultRollback=true)
public class MyServiceTest extends AbstractJUnit38SpringContextTests {
@Autowired
private MyService myService;

@BeforeClass
public static void setUpClass() throws Exception {
}

@AfterClass
public static void tearDownClass() throws Exception {
}

@Test
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull( id );
if( id < 1 ){
fail();
}
}
}

The problem is that this test will fail because transaction was rollbacked, but the insert is OK!
If I remove `@TransactionConfiguration(defaultRollback=true)` then the test pass but a new record will be inserted into database.

@Test
@Transactional
@Rollback(true)
public void testInsert(){
long id = myService.addPerson( "JUNIT" );
assertNotNull(id);
if( id < 1 ){
fail();
}
}

Now can test pass correctly, but rollback is ignored and the record is inserted into the database.
I have annotated the method `addPerson()` inside myService with `@Transactional`, obviously.
Why is the rollback being ignored?
Reply

#2
check out

[To see links please register here]


Section 8.3.4 in particular

Spring has some classes for testing that will wrap each test in a transaction, so the DB is not changed. You can change that functionality if you want too.

Edit -- based on your more infos, you might want to look at


AbstractTransactionalJUnit38SpringContextTests at

[To see links please register here]

Reply

#3
You need to extend transaction boundaries to the boundaries of your test method. You can do it by annotating your test method (or the whole test class) as `@Transactional`:

@Test
@Transactional
public void testInsert(){
long id=myService.addPerson("JUNIT");
assertNotNull(id);
if(id<1){
fail();
}
}

You can also use this approach to ensure that data was correctly written before rollback:

@Autowired SessionFactory sf;

@Test
@Transactional
public void testInsert(){
myService.addPerson("JUNIT");
sf.getCurrentSession().flush();
sf.getCurrentSession().doWork( ... check database state ... );
}
Reply

#4
If your

myService.addPerson("JUNIT");

method is annotated like @Transactional you will be getting some different kind or errors trying to fix this. So you better just test DAO methods.
Reply

#5
Use Following annotation before class :

@TransactionConfiguration(transactionManager = "txManager",defaultRollback = true)
@Transactional

here `txManager` is application context's Transaction Manager.

Here `txManager` is an instance or bean id of Transaction manager from `application context`.

<!-- Transaction Manager -->
<bean id="txManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="txManager" />

Add your code inside `setUp()` method, this will execute in start of the test and the last wrap up code should be put in `teatDown()` method that will executed at last. or you can also use `@Before` and `@After` annotation instead of it.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through