views:

114

answers:

3

The parts of any repository/DAO implementation worth testing are the queries. To ensure that these queries are correct, you'd have to run it in the actual database.

Given the above facts does it make sense to unit test DAOs/Respositories? If yes what are the best practices?

+2  A: 

Yes - with an in-memory database (HSQLDBL for example)

This blogpost of mine discusses a similar topic.

Update: about your comment - in the post I linked an ORM is used to make sure database inconsistencies aren't a problem. Working with raw SQL isn't quite a good idea in the first place (if working with OOP). Then, you could always try to use as ANSI SQL as possible (and not test the inconsistencies).

Another option might be to dedicate a testing database server + a continuous integration engine, and run the tests only within the engine (so that multiple test executions from multiple machines don't mess with each other)

Bozho
Since most RDBMS servers differ from each other in the way they handle SQL, how can we be sure that it will work on our production server just because it worked on the in-memory DB and vice versa?
Chandru
if you want to ensure everything works, then you also need to do integration test
Anton Setiawan
Voted up for a helpful answer. However, using ANSI SQL alone is not an option. :(
Chandru
+1  A: 

I unit test my repositories pretty religiously. They are probably my most important unit tests actually.

This can actually be quite painless if you use an ORM such as NHibernate.

I use a base fixture that contains setup and teardown for creating an in memory sqlite db and then destroying it at the end of each test. This is surprisingly quick. Then for each repository I have a setup that injects my test data for my tests. This is very self contained and catches all the logic issues in my repository queries.

The only thing it doesn't catch is db provider specific cases, but when using something like NHibernate these are usually the exception.

For the special cases where you are testing database specific queries you may need to have a suite of tests that use a different setup and teardown methodology. Unfortunately these tests would be slower and likely more fragile than your other unit tests (that's why they should be grouped together).

If "express" editions of the database software you are testing are available I still recommend that the database be set up locally on the fly so that you always ensure that the database your tests run against has the schema they expect. I would change one part of the setup and teardowns of this though. I would only setup and teardown the database at the beginning and end of the entire run of tests. Then every tests setup and teardown should start a transaction, then roll it back at the end. This is a quick way of keeping things compartmentalized between the tests. The last thing you want is for data from one test to affect another test.

mockedobject
I do use Hibernate (Java) but my app uses a bunch of native SQLs to utilize few Oracle specific statements which are not available on other servers.
Chandru
I added some information about what I have done in the past when I needed to use a specific sb and not just an in-memory test. I prefer not to have to because it is more work, but it can still be done relatively painlessly.
mockedobject
Accepting for detailed explanation.
Chandru
A: 

Yes doing unit tests for DAO layer is a must. In java there are frameworks like dbUnit helps you in doing that. Keeping a separate schema/instance in the database with some bootstrap data will help you do right unit testing and you can cover most of the scenarios.

Teja Kantamneni