karmapolice
karmapolice

Reputation: 336

doubts about unit testing DAOs

I am looking for information to build unit test for typical DAO methods (find user by username, etc.) and I found several examples using mocks like this one: http://www.christophbrill.de/de_DE/unit-testing-with-junit-and-mockito/

@Test
public void testComeGetSome() {
    // Mock the EntityManager to return our dummy element
    Some dummy = new Some();
    EntityManager em = Mockito.mock(EntityManager.class);
    Mockito.when(em.find(Some.class, 1234)).thenReturn(dummy);

    // Mock the SomeDao to use our EntityManager
    SomeDao someDao = Mockito.mock(SomeDao.class);
    Mockito.when(someDao.comeGetSome(1234)).thenCallRealMethod();
    Mockito.when(someDao.getEntityManager()).thenReturn(em);

    // Perform the actual test
    Assert.assertSame(dummy, someDao.comeGetSome(1234));
    Assert.assertNull(someDao.comeGetSome(4321));
}

There is also a similar one in Lasse Koskela's book using EasyMock instead of Mockito.

The thing is: what are we really testing in these examples? We are basically telling through mocks what object the query should return, and then asserting that in fact it returned the object we told it to return.

We are not testing if the query is correct or if it returns a different object or no objects at all (or even more than one object). We cannot test if it returns null when the object does not exist in the database. This line

Assert.assertNull(someDao.comeGetSome(4321));

works because there is no scripted interaction for that argument, not because the object does not exist.

It looks like we are just testing if the method calls the proper methods and objects (em.find).

What is the point of unit testing this? Are there any good frameworks in Java to quickly set up an in memory database and perform tests with it?

Upvotes: 2

Views: 2758

Answers (2)

Artem Larin
Artem Larin

Reputation: 162

Your doubts really make sense. Actually there is no need to test DAO with unit tests in most cases because unit tests deal with one layer, but DAO cooperate with database layer.

This article explains this idea: http://www.petrikainulainen.net/programming/testing/writing-tests-for-data-access-code-unit-tests-are-waste/

Hence we should test DAO and database layer with integration tests. Integration tests take into account both DAO and database layer.

This article will provide your with Spring + Hibernate example: https://dzone.com/articles/easy-integration-testing

Upvotes: 3

DieZZzz
DieZZzz

Reputation: 135

It looks loke more like service tests, than a real DAO tests. For example, I'm using dbunit to test my DAO layer.

For example, I have Author table with 2 fields: id and name. I'm creating a dataset xml file like

<?xml version="1.0" encoding="UTF-8"?>
<dataset>
    <AUTHOR AUTHOR_ID="1" NAME="FirstAuthor"/>
    ...
    <AUTHOR AUTHOR_ID="10" NAME="TenthAuthor"/>
</dataset>

And then in my test class using Mockito I'm testing my DAO methods like

@Test
@DatabaseSetup(value = "/dao/author/author-data.xml")
public void testFindAll() {
    List<Author> authorList = this.authorDAO.findAll();
    assertEquals(10, authorList.size());
}

Upvotes: 1

Related Questions