Adam Warski

30 Nov 2010

DB test: run tests with a database using Arquillian

testing
jee
hibernate
java

DB test is a set of helper classes which let you run tests that use a database. By default each test has a separate, in-memory H2 database, providing fast startup time and isolation. A fairly large test runs on my machine in 3 seconds, so you can include such tests in your testsuite without a big overhead. Such tests are perfect for:

  • validating entity configuration (proper usage of annotations, hibernate.cfg.xml) – the normal Hibernate configuration sequence is done
  • testing query syntax (named and regular queries) and complex queries
  • testing methods which heavily use the EntityManager and would be hard to test otherwise

DB Test is based on Arquillian and can be used in applications that use CDI (e.g. Weld) for dependency injection and component management.

A very basic test looks like this:

public class MyEntityDAOTest extends AbstractDBTest {
    @Override
    public void configureEntities(Ejb3Configuration cfg) {
        cfg.addAnnotatedClass(MyEntity.class);
    }

    @Deployment
    public static JavaArchive createTestArchive() {
        return new ArchiveConfigurator() {
            @Override
            protected JavaArchive configureBeans(JavaArchive ar) {
                return ar.addPackage(MyEntityDAO.class.getPackage());
            }
        }.createTestArchive();
    }

    @Inject
    private MyEntityDAO manager;

    @Test
    public void testEntityManager() {
        manager.persist(new MyEntity(10l, "test"));
        assertThat(manager.findById(10l).getText()).isEqualTo("test");
    }
}

Inside MyEntityDAO we can normally use an EntityManager, e.g.:

public class MyEntityDAO {
    @Inject @Writeable
    private EntityManager entityManager;

    // methods

(@Writeable is one of the qualifiers from softwaremill-cdi: using them you can inject both a RO and RW entity managers).

A full example: TestOfDBTest can be found in the tests for the DB test module (yes, a test testing helper classes for tests! :) ).

All test methods are surrounded with a JTA transaction. If needed, another database can be used (e.g. mysql/postgres/etc): you can change any of the Hibernate configuration settings in the configureEntities method, just as in a normal configuration file (persistence.xml or hibernate.cfg.xml).

Moreover, before each test an sql script is optionally executed, which can be used to populate the DB with test data. The name of the sql file is the same as of the test class.

You can find the code in the softwaremill-db-test module of softwaremill-common library, which is licensed under the Apache2 license.

Update: New module URL.

Adam

comments powered by Disqus

Any questions?

Can’t find the answer you’re looking for?