Technology with opinion

Wednesday, September 23, 2009

Unit Testing - Mocking to test Edge Cases with NHibernate

Sometimes in code you want to test edge cases, some of these can be difficult to test even with integration tests because of database constraints, etc.  This may be a business key or unique identifier (that's not a primary key)- may be enforced or not.  The key is you make an assumption that in code you want to test for.  Mocking dependencies is the key here, to create behavior that would not otherwise be possible.

Unlike the pattern illustrated by Ayende or that I added onto here, I wanted NHibernate's SessionFactory and Session objects to return data that I could not return from the database because of unique index constraints.

In this scenerio I'm returning data from the database that matches certain values and it should always return a list that contains either 0 or 1 objects otherwise it throws an exception:

Problem is that integration tests are unlikely to uncover this error with normal data and end user testing won't uncover it either.  This is simple, but I want to make certain that the exception is correctly thrown.

The only tricky part really is that after mocking the ISessionFactory & ISession objects you need to also mock each ICriteria object returned from the Session object.  So with Rhino Mocks after telling it to expect a call to CreateCriteria that returns an ICriteria, we also need to create expectations for this result calling Add and its result calling list.  This is because fluent interfaces use method chaining which makes this part a little tedious:

This allows us to now test what would actually happen if more than one Animal objects were returned.  NHibernate makes this easy because there are interfaces for pretty much every object.

FYI: this code uses Rhino Mocks, NBuilder, NUnit & NHibernate

No comments: