Eliminate Database Dependencies in Test-Driven Development
How to avoid the end-to-end integration test problem with the Repository pattern.
- By Benjamin Day
Many developers are tasked with writing unit tests as test-first design and development becomes commonplace, even on teams that aren’t strictly practicing Agile methodologies. Test-driven development (TDD) can produce cleaner code by requiring project teams to first write unit tests that fail, then program just enough code for a needed function, retest, refactor and repeat the cycle. If you haven’t written code using TDD, starting from a failing test sounds awkward. But it’s this extra bit of thought about what you want to achieve that gives you a clearer understanding of what you need to accomplish.
If you’re writing an n-tier application using Visual Studio and you’re using TDD, it’s not uncommon that your unit tests for business-tier functionality read and write to a database. In order for these tests to run, you need a running database with the most up-to-date schema along with any supporting data.
What if you’re writing unit tests for a service-oriented application and your code needs to make calls to a Windows Communication Foundation (WCF) service running on a different machine? Or it makes calls to a mainframe or some other back-end system? At this point, is it even practical to write integration tests to these systems?
The solution to this end-to-end integration problem is to start using the Repository pattern in order to “mock out” your database or other back-end systems and decouple your application logic from these dependencies. Martin Fowler describes the Repository pattern by saying it “mediates between the domain and data-mapping layers using a collection-like interface for accessing domain objects” (“Patterns of Enterprise Application Architecture,” Addison Wesley Professional, 2002). If your business tier uses your Repositories as interfaces, then you can easily drop in mocked versions to use from your tests and then drop in the database versions at run-time. In the end, you’ll have a way to test your business-tier functionality without requiring a running database or other back-end system. As a side effect, your code will be easier to maintain because you will have decreased the level of coupling in your application.
In this article, I’ll show you how to leverage the Repository pattern to eliminate the dependency on SQL Server from your unit tests and, in the process, improve your application’s testability. The unit-testing features that I discuss in this article are all available in Visual Studio 2008 Professional Edition and in all Visual Studio 2008 Team Editions. The sample application is written in Visual Studio 2008 Team Suite and requires an instance of SQL Server or SQL Express. See the readme.txt for information about how to set up the database and where to find the connection string.
— Want some help with Test-Driven Development (TDD)? We teach it and do on-site coaching & mentoring. Contact us at firstname.lastname@example.org. Check out our public course schedule and read the description of our TDD and Team System courses.