views:

216

answers:

1

I was running into this error

An attempt to attach an auto-named database for file C:\<...>\Out\MessagesDB.mdf failed. A database with the same name exists, or specified file cannot be opened, or it is located on UNC share..

attempting to write some unit tests for testing a controler. I belived the problem was that the tests were attempting to not use the database I had defined in the main project. So I modified the connection string in the tests to

In the App.config for the test project I'm using

<connectionStrings>
    <add name="MessagesDBConnectionString" connectionString="Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\MessagesDB.mdf;Integrated Security=True;User Instance=True"
      providerName="System.Data.SqlClient" />
</connectionStrings>

and then overrode the DataDirectory by doing

AppDomain domain = AppDomain.CurrentDomain;

        String currentDirectory = System.Environment.CurrentDirectory;
        String DataDirectory = currentDirectory.Substring(0, currentDirectory.IndexOf("TestResults")) + "Server\\App_Data";
        domain.SetData("DataDirectory", DataDirectory);
        db = new Server.Models.MessagesDBDataContext();

Which works great but looks like a hack. How should I have done this?

Edit:

I took another look at this terrible mess today and based off of the Nerd Dinner example I removed all direct calls to the database from the controllers in my project and moved them into a repository object which implements an interface (IRepository). Then I created a fake repository object which also implemented IRepository. I added a constructor to each controller which allowed passing in an IRepository to be used. The default controller constructor was then changed to initialize a repository. The tests no longer talk to the database so they are faster and far less destructive.

+6  A: 

The standard approach is to mock out the database. That means the class you're testing takes a parameter which provides data, and looks like a database connection.

In the unit tests, you actually pass in an implementation that provides hard coded data.

There are tools which can help you with this, for example by saving the results of a database query into a config file, so that you can set up the test with real data, but it will load quickly and never change because it is now saved in a file separate from the database. SnapDAL is one tool you can use for this.

RossFabricant
Could you elaborate on the kinds of tools that can do this? Me want!
Stuart Branham
Rhino Mocks and Moq will do the mocking for you.But how familiar are you with interfaces?
Chris Brandsma