Archive for March 2006

Some musings on unit tests and databases

I just read Dave Donaldson’s unit testing guidelines. Basically good advice.

One point missing from this article and many others, is a good description of what a test should consist of.

A single unit test consists of 3 parts

  • creating an environment,
  • executing some code, and
  • asserting one or more expectations.

An environment is usually a temporary construct, but sometimes the nature of the environment dictate that it may persist after the test has completed. An example is a test that writes to a database. In that case, you need to add a 4th step which is to clean up after yourself.

If you are spending a lot of time, or having difficulty creating and cleaning up your environment, then that is a code smell. It usually indicates a high degree of coupling, i.e. that your code has a lot of dependencies. Sometimes this is ok – there are points in your code (typically business logic) that require a lot of knowledge, and that knowledge exhibits as dependencies.

But sometimes it represents a real problem. Needing to access a database in your unit tests is an example of inadequate separation of the layers of your application. Ideally, you should be able to mock out any aspect of your code, especially other layers, and most certainly the database. However, the tools to do this are either not available or are clumsy.

In my current project, I have been fortunate enough to have been able to construct my own framework from scratch, including a mock database implementation. I am here to tell you that it is truly liberating to have tests that access data but do not require a real database connection. I look forward to a time when tools mature enough to enable this for everyone.