In general, I'd recommend against testing things against a live database for a few reasons:
- Executing SQL can make your tests take a long time
- Data can change under your nose, resulting in broken tests even with no visible code changes. You want your tests to be isolated and deterministic, so they pass or fail only when your code changes.
- If you have code which updates a database, you need to roll back your changes or your next test run could result in a false positive or false negative.
So for testing, you want to fake out your database. Start with something like this:
public interface IDataRepository {
Customer GetCustomerByName(string name);
void SaveCustomer(Customer c);
SecurityToken Login(string username, string password);
}
class DatabaseRepository : IDataRepository { ... } // invokes your stored procedures
If your classes need something from the database, pass an IDataRepository
into your object's constructor.
Nice thing about this setup is how you can create a FakeDataRepository
implementing the same interface -- it doesn't invoke anything, only returns hard-coded data. You can return data for the happy case, for the exception case, and other needs.
In other words, you're not testing the interaction between your classes and database at all -- the point of a unit test is to test a single piece of functionality without caring about the other moving parts in your app.
Now if you need to test your stored procedures, you should can write tests for your DatabaseRepository
class directly.
You need to re-set your database to its original state after each test -- so you either run everything in a transaction and rollback, or you create a new database with scratch data on each test run. I prefer the latter approach -- its just too easy to leave a transaction open or forget to roll it back, and therefore destroy all of your test data.
Database tests like this can take an arbitrarily long time to execute, so you're probably best creating a separate project strictly for testing your database (especially if you have a few hundred stored procedures).
I'd think of this as more a system or integration test, not a unit test.