Question

I've set up a test database to begin unit-testing an app that I've recently been added to. It is a 3-tier design (presentation layer, BOL and DAL) and this is my first time writing unit tests.

I've decided to start at the BOL and I figure the best way is to swap out the ConnectionString (which has been passed along as a Shared String) with one that points to my new test database. However, I don't wish to change any production code. I simply wish to somehow redirect the app to the test database during unit tests. How might I go about accomplishing this?

Was it helpful?

Solution

What I usually do is create a configuration section that holds the functionality to determine which connection string to use.

Here's a basic example:

static ConfigurationSettings
{
     static String ConnectionString
     {
        get
        {
           var result = "TESTCONNECTIONSTRING";
           if (ConfigurationManager.ConnectionStrings["SOMEKEY"] != null)
               result = ConfigurationManager.ConnectionStrings["SOMEKEY"];
           return result;
     }
}

This way, I don't have to worry about how to connect to the system, and you can also override this behavior in your tests to accomplish what you want by adding a setter.

The reason why I don't go the multiple config file route, is that I can't use the config files when running in a test suite (such as the NUnit testrunner).

OTHER TIPS

Does your connection string come from a config file? Can you set up a matching config in your unit tests?

As you will probably soon learn anyway, static/Shared code is considered evil in unit testing, for a number of reasons. One of these reasons is that it is difficult to change the values during unit testing.

It is a much better idea to pass your Dependencies explicitly to your System Under Test (SUT) - preferably in the constructor. In your case, you should pass the connection string to the SUT via its constructor.

An even better approach would be to abstract away the Data Access Layer behind an interface and pass an instance of that interface to the SUT.

I've written a bit about Imperative Configuration, but in general, you should read Roy Osherove's book The Art of Unit Testing - it deals with a lot of these issues.

It is a common practice to keep connection strings in a config file. If you do this, then just use different config files in different contexts.

There's a possibility also if you don't (but you may have to change production code). Let the connection string be injected via constructor or a setter. Then, in production, you use the production connection string; and in the tests, you can connect to your test database.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top