Unit Testing NHibernate DALs – What Are You *Really* Testing?


Someone new to NHibernate recently asked me how to unit test their data access layer which uses NHibernate.  I’ve already sent him my thoughts on it, but figured it may make for a good blog post to get some of the community’s reaction. 

What Are You *Really* Testing?

From my perspective, there are (at least) a couple questions you should always be asking yourself when practicing TDD or just testing in general:

  1. What am I really testing here?  My code or 3rd party/framework code? 
    • At some point you need to trust the frameworks your using or else you’ll end up testing the whole .NET framework…   Not good!
    • How much value is really being gained from this test that I am writing?  A quick quiz…
      • Which test do you think would bring the most value?
        • a) A unit test which uses a mocked ISession to verify that when Save(entity) is called that NHibernate does what it’s supposed to do?
          • b) A unit test to make sure NHibernate is generating the correct sql for an HQL query or Criteria call which it’s supposed to do?
            • c) An integration test which verifies that the mapping files you’ve written are configured correctly to map your domain objects to your database tables?</ul>
            • Answer?  More than likely, C is probably the best answer to this question.  If all you have are unit tests with no state-based integration tests, that’s probably a bad sign.  At some point you’ve got to write integration tests to make sure all your components work together, especially in your data access/persistence layer.</ul> </ol>


          Now, if for some reason you have another layer of abstraction in there like PersonRepository -> IPersistenceFacade -> NHibernate, then driving out the interaction between your PersonRepository and IPersistenceFacade is probably a good idea.  But that’s probably as far down as I’d go for unit tests.

          Also, if you’re not using an ORM and have to use vanilla ADO.NET to hand roll your own data access/mapping layers, then I would most definitely recommend driving that out using TDD and unit tests.  But hopefully this is not something you’re having to do for the most part.

          Final Thoughts

          So far in my current project, I’m only using integration tests for my persistence layer (aka DAL) to verify that my mapping files are correct.  The nice thing is that NH makes this really easy with its SchemaExport tool to very easily generate your database schema from your mapping files.  So I’m using that along with a couple hand-rolled utilities and factories for generating and inserting sample data to use for integration testing purposes.

          Of course, having automated unit tests for as much of your application as possible is still a great goal, but sometimes it needs to be weighed against how much business value it’s going to help you deliver in terms of increasing the maintainability and testability of your code.  However, when in doubt, write a test!

          Your Thoughts?

Creating Composite View Components In MonoRail / Refactoring Exercise