Archive

Like many architects and developers, I believe that test driven development can have its place and be a worthwhile endeavor for certain projects and skill sets. The advantages and disadvantages of this methodology are well chronicled. Whether or not you are a practitioner of TDD, I hope that at a minimum, you’re writing unit tests using a framework such as NUnit or the built-in Visual Studio Unit Test Framework.

If you’re working in an ideal environment, you probably have a system that has been designed with testing in mind, unit tests have been well written and categorized, external dependencies such as the database have been mocked and stubbed, you’re using a build server that will run the tests and if they fail, notify the developer. While some practice this application life cycle discipline, I would venture to guess many more do not. If you fit into the latter category, you may not yet have the resources or know-how to be stubbing and mocking. If this is the case, I believe that all is not lost.

I have spent considerable time coding a domain specific language (DSL) that I call Frameworks. It has the ability to create many different types of artifacts including those for the data access layer. If you have a table called Shape, it will create the Shape Entity object as well as the Shape data access object (DAO). The DAO then uses an ORM to communicate with the database. If desired, artifacts will also be constructed for their interface counter-parts, that is IShape and IShapeDao. Dependency injection configuration is constructed allowing a natural integration with an Inversion of Control container.

These interfaces and separation of dependencies allow for the greatest unit test flexibility. Now that we have achieved all this flexibility, one must decide how to use it. I am completely aware that removing dependencies from a unit test is highly desirable hence all the work to make this happen automatically. One formidable dependency in most business applications is data access. Mocking is a very effective and popular way to remove this dependency from your tests. Mocking can be fairly straight forward if you have designed your system appropriately.

There are plenty of compelling reasons to ‘fake’ the database and they include but are not limited to:

The database or data access layer could have defects which could give you false positives or false negatives in your test results.

The database might not be ready for testing as it could be lagging behind the code.

The database could be sitting on a server that is not be readily accessible to duplicate for the purposes of testing.

The work that needs to be performed in order to ready a database for testing could be beyond scope.

Database configuration issues get in the way.

There is a dependency on not only the database, but the type of data that is needed.

There are thousands of unit tests and all the reading and writing to the DB slows testing down to a crawl.

As compelling as this list is, it doesn’t mean that you can’t build useful tests that depend on the database. They’re just no longer called unit tests, rather they would be integration tests. I find myself asking what is a dependency in the first place. I would argue that every unit test incurs some dependency. For example, we have to depend on the compiler, the CPU and other ‘moving’ parts.

To this end, what if a code generator created everything from the DDL to create the database, to the data access objects to service CRUD? Once the code generator is tested, what is the difference between this code generation and that of the compiler to create MSIL code?

In summary, I think bypassing the classic definition of a unit test in favor an integration test accomplishes the goal in a smaller scale project. If the project is mission-critical, scalable, functionally complicated or expected to have a long-life, use an isolation framework such as Moq. Deciding how to proceed is what architecture is all about; one size does not fit all!