chaldaean
chaldaean

Reputation: 1232

Junit testing DAO layer with Spring and Hibernate

I try to test simple class:

public class GenericDAO {

    @Autowired
    protected SessionFactory sessionFactory;

    public <T> Serializable create(final T o) {
        return sessionFactory.getCurrentSession().save(o);
    }

    @SuppressWarnings("unchecked")
    public <T> T find(final Class<T> cl, final long id) {
        return (T) sessionFactory.getCurrentSession().get(cl, id);
    }

    @SuppressWarnings("unchecked")
    public <T> T update(final T o) {
        return (T) sessionFactory.getCurrentSession().merge(o);
    }

    public <T> void delete(final T o) {
        sessionFactory.getCurrentSession().delete(o);
    }

    @SuppressWarnings("unchecked")
    public <T> List<T> getAll(final Class<T> cl) {
        return (List<T>) sessionFactory.getCurrentSession()
                .createCriteria(cl).setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY).list();
    }
}

In my test class I use @Before to create session and fill database for testing, something like this:

    @Autowired
    protected SessionFactory sessionFactory;    

    @Before
    public void setUp() {
        Session session = sessionFactory.getCurrentSession();
        session.save(user);
        session.save(user1);
        session.save(user2);
        session.flush();
        // Otherwise the query returns the existing order 
        session.clear();
    }

As for me it is better to use @BeforeClass to fill db, because I need to create test date only once at the begining of class. But this method must be static so I cannot autowired sessionFactory. So what is the best solution for this?

Upvotes: 0

Views: 2279

Answers (1)

Aaron Digulla
Aaron Digulla

Reputation: 328594

My solution for this problem is to implement DataSource in such a way that it forwards all method calls to the real data source.

When a connection is requested from my DataSource, I check if that's the first connection (just a boolean flag). If it is, I set up the database before I return the connection.

Pseudocode:

getConnection() {
    conn = delegate.getConnection()
    if( firstConnection ) {
        firstConnection = false;
        setupDatabase( conn );
    }
    return conn;
}

That also makes the DB setup lazy.

Note: Your code tests a lot of things that you shouldn't: Hibernate, JDBC, the DB driver, the database. Generally, you should assume that these pieces work or are tested by someone else.

For most tests, it should be sufficient to mock the GenericDAO.

Upvotes: 1

Related Questions