DAO Unit testing
Asked Answered
A

5

26

I have been looking at EasyMock and tutorials/examples around using it for Unit Testing DAO classes, for an "outside container" test. However, I think most of them talk about testing the Service Layer instead, mocking the DAO class. I am a bit confused, is it really how you Unit Test the DAO layer?

Some would say that the tests interacting with DB & EJBs are actually Integration tests and not Unit tests but then how would you know if your SQL is correct (assuming no ORM) and your DAO inserts/queries the right data from your real (read, local database which is similar to that in production) database?

I read that DBUnit is a solution for such a situation. But my question is about using a framework like DBUnit "outside container". What if the DAO depends on some EJBs, how do we handle the transactions, what happens if there are triggers that update other tables on your inserts?

What is the best way to Unit Test only the DAOs with such dependencies?

Akihito answered 21/3, 2012 at 15:13 Comment(2)
I do not think the test of DAO methods is a good idea, because in such case you are testing the queries and underlying ORM framework (if you use one). I read the comments of other people and I see many people provides with an advice to perform unit tests against the DAO methods and to use in-memory DB in this case. I do not know if they tried to implement that, but issue here is that the different DB lead to different syntax in some cases and do not tell me that ORM layer can save you from that, it could, but still your tests are inconsistent when you perform them against different DB.Poss
(...continue of previous comment) So what is the point then to have inconsistent tests? This kind of tests test nothing and give you warped view on correctness of functionality you test with theme. And at the same time it introduces SO MUCH problems into the project.Poss
M
32

Personally, I unit test DAOs by hitting some sort of test database, preferable the same type of database (not the SAME database, obviously) that your app uses in production.

I think if you do that, the test is more of an integration test, because it has a dependency on a running database. This approach has the benefit in that it is as close as possible to your running production environment. It has the downsides that you need test configuration, you need a running test database (either local to your machine or somewhere in your environment) and the tests can take longer to run. You also need to be sure to rollback the test data after tests execute.

Once DAOs are tested, definitely mock them to unit test your services.

Millen answered 21/3, 2012 at 15:28 Comment(2)
wouldn't it be an Integration Test then?Professor
Yes. This is obviously not a unit test.Supination
C
18

Typically with DAOs the idea is to have a minimal wrapper around data-access code, so there's nothing there to test except for the mapping to the database, and unit tests with mocks are useless. If there is actually logic in the DAO worth testing with mocks, then an argument could be made that you're misusing the DAO pattern and that the logic should be in a service.

For testing the mapping to the database DBUnit is useful because it allows you to specify a starting dataset before the test so your test starts from a known state, and it allows you to specify what the ending state of the data should be, so you don't have to write a lot of unit test code asserting what is there is what is expected.

Ideally if you have a tool like Hibernate that abstracts the database away you can get by with using an in-memory database like H2 or HSQLDB, so your tests run faster and there's no database to create. If you do have to use a real database make sure your tests have it to themselves so they can create and delete data without impacting or being impacted by other processes. In practice having a database to yourself, both locally and in CI environments, is unlikely and using the in-memory database is much more practical.

Cowey answered 4/4, 2012 at 14:6 Comment(0)
V
3

Complementing on Koya anwers, you can use HSQLDB for DAO testing. I imagine you have use Spring and Hibernate in your project. You would need separate configurations files to point for the HSQLDB, you would need to insert data prior to execute the tests. There are some limitations to what you can do with HSQLDB, but it is OK for general use as queries and joins. With this solution can be used in a continous environment , such as jenkins. Integration tests could use the HSQLDB , so this part is not mocked.

Ventail answered 17/1, 2013 at 17:43 Comment(0)
S
2

I am using HSQLDB for Dao and Service API testing. The performance is good and it supports transactions too. I am not using EJB. I use Hibernate.

There are some issues that I am aware of that running the tests on a different database may mask some of the supported database issues. But I think such issues should be caught in the smoke & acceptance tests.

regards, Koya

Sielen answered 4/4, 2012 at 13:18 Comment(0)
A
0

[Edited Mar 2022] I ultimately settled for writing the Unit Integration tests that can run outside the container, with a living database and using a standalone transaction manager from Bitronix for transactional support, the instance of which I setup & tear-down with every run. This lets me rollback the transactions as well.

Akihito answered 14/5, 2012 at 14:19 Comment(2)
You are doing e2e test which is also knows as integration test.Supination
You are correct @SupinationAkihito

© 2022 - 2024 — McMap. All rights reserved.