views:

173

answers:

4

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?

+1  A: 

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

Paddy
Yes it does. I supopse it's probably possible, I'm not sure how I'd go about this. Thanks!
Chris
A: 

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.

Samuel Carrijo
A: 

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.

Mark Seemann
+2  A: 

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).

Joseph
There are parts to this answer that make a lot of sense, but I'm not so clear on the actual code you've posted. It doesn't make a whole lot of sense to me.
Chris
@Chris I posted it in C#, is that why? I can edit my answer into VB.NET if you would prefer. Or is the confusion elsewhere?
Joseph
It is not because it is in C#. There are two things which throw me off. Number 1, where would the code you pasted reside? The configuration file is simply an xml file, so how would I place logic such as the above code into it? Number 2 is your if statement. How would this give me a different connection string based on whether I'm running my unit tests or simply running the code? Thanks for the follow-up.
Chris
@Chris 1. The code should be placed in some Configuration namespace/project in your application. 2. The property gives you different connetion strings at run time based on whether or not you do or do not have a config file (web.config or app.config). For unit tests, you will not have a web.config or app.config (at least not one you can manipulate), so the hardcoded string will be used.
Joseph