views:

146

answers:

2

Hi, I'm testing the CRUD operations of my DAOs in JUnit tests. When i execute the single test, Hibernate always resets the schema and populates the DB in a known state. But when i execute multiple tests in a row, Hibernate resets the schema once, and then the data is accumulated during the execution of the tests.

This is an unexpected behavior, so I'd like to add in the @Before method of the tests a function that explicitly resets the schema to avoid the pesistence of side data created by previous tests during the execution chain.

Any tips?

Thanks

+2  A: 

First of all, what you're doing is not unit testing, it's integration testiong.

Tips:

  • Use transactions and roll the back.
  • Consider using DBUnit (not sure how helpful it would be in your case).
  • Here's some relevant code from org.springframework.orm.hibernate3.LocalSessionFactoryBean.

...

Connection con = session.connection();
Dialect dialect = Dialect.getDialect(getConfiguration().getProperties());
String[] sql = getConfiguration().generateSchemaCreationScript(dialect);
executeSchemaScript(con, sql);
lexicore
+1  A: 

You could begin a transaction before and rollback the transaction each @Test method, something like this:

public class HibernateIntegrationTest {
    protected static SessionFactory factory;
    protected Session session;

    @BeforeClass
    public static void createSessionFactory() {
        AnnotationConfiguration config = new AnnotationConfiguration();
        // ...
        config.configure();
        factory = config.buildSessionFactory();
    }    
    @AfterClass
    public static void closeSessionFactory() {
        if (factory != null) {
            factory.close();
        }
    }
    @Before
    public void beginTransaction() {
        session = factory.getCurrentSession();
        session.beginTransaction();
    }
    @After
    public void rollbackTransaction() {    
        if (session.getTransaction().isActive()) {
            session.getTransaction().rollback();
        }
        if (session.isOpen()) {
            session.close();
        }
    }
}

And extend this class in your tests classes.

public class DemoTest extends HibernateIntegrationTest {
    @Test
    public void createMyEntity() {
        MyEntity e = new MyEntity();
        //...
        session.save(e);

        assertNotNull(e.getId());
    }
}

Note that this is not the cleanest way to do this, the code above is more for demonstration purposes.

Pascal Thivent