views:

255

answers:

3

I'm looking at setting up unit tests and integration testing, but I've run into the problem that the connection string in the web.config is unavailable for testing. The solution we've come up with to get around this is to have another connection string for testing, but I was wondering if there was a better way.

The other half of the issue is setting up and tearing down the test db. Right now we just have a giant test that sets up the db before running and then tears it down afterwards. That way we can control the order that the test run to make sure the results are proper.

Just looking to see if there are better ways/tools to use for testing an ASP.Net app.

A: 

The recommended approach is to architect your system that you can test your code without a DB. What this means to a code perspective is using seperation of concerns. You want all of your core business logic seperated from your pages. You can do this using a MVC or MPV pattern, which if you good you can find a great deal about.

Right now there is ASP.Net MVC; however, the MVC pattern has been used in ASP.Net long before this framework existed so if your looking at enhancing an existing web forms app make sure you don't end up looking at the more recent buzz which is about ASP.Net MVC as a programing model in ASP.Net.

Now let's say you have your core logic for handling a button click isolated from page so you have a Class let's call it WidgetController. The widget controller might have a method of HandleClick() which performs your business logic.

Let's further assume that your business logic requires data access. You can again use seperation of concerns. Your business logic shouldn't care how to access the DB, all it needs is the data let another class get the data. A popular way of seperating data is by using a Depedancy Injection or Inversion of Control model (DI, IoC respectivley). Essentially what you do is define an interface for your data access, and your controller will program against the interface. You then at runtime provide the actual class to your controller via some method (Property, Constructor etc...)

What this does is it allows you to provide MOCK implementations during runtime which seperates your DB. The mocks will implement your interface and you can just new up the objects your tests will need store them in memory.

JoshBerke
A: 

In your unit tests, isolate the data access code and abstract it (usually using interfaces, e.g. the repository pattern) so that you don't have any database code in your unit tests. Instead, mock your data access abstractions, using a mocking framework (e.g. Moq). That way, your tests will run fast, which is what you need to ensure you run all your tests often.

When you need to test the whole system, including the database, you're doing integration testing. For that, take a look at Fitnesse. There's a good book on it.

Mike Scott
+1  A: 

Actually, as mentioned mocking and using stubs to test system interaction without a database interaction is great, but intergration testing can be just a valid.

What you mention with regards to scripting out the database tables and data, then running a setup script prior to all integration tests, is a fairly sensible approach.

Dont know how much of a fan of ORMs you are, but using NHibernate you can rebuild your tables from the mappings. After rebuilding the database I usually just have a script that physically creates the objects and persists them via NHibernate. I know this isnt the best approach but I usually find that the amount of startup test data I need isnt that large, and also inserting via NHibernate is a test itself :-).

I have never used Fitnesse as mentioned by "Mike Scott" but I have heard good things and it does look interesting. It is also recomended in the infamous Billy McCafferty article which gives a nice breif introduction to some great general development best practices such as unit testing, ddd, design-by-contract etc..

Owen