user3900102
user3900102

Reputation: 69

Unit Testing Legacy Code without DI

We are trying to add unit testing into our Business layer. The technology stack is asp.net web forms, WCF, ADO.Net calling stored procedures). The business layer is calling static methods on data classes, so it makes it difficult to introduce DI without making a lot of changes.

It may not be a conventional way to do it, but I'm thinking of keeping the DB in the unit test (dependency), but using it as a Test Db... either using an existing frozen db or having mocked data in tables. I was wondering about the feasibility of using a test db where the stored procedures are used like Mocks. Instead of duplicating the entire db, just create table names, named by the stored procedure. The stored procedure would just call one table, and return static data... essentially, trying to emulate the functionality of Mocking data with something like Moq but from a DB perspective.

Can anyone recommend any designs that would include the DB in testing, that are still deterministic?

Upvotes: 3

Views: 290

Answers (2)

StriplingWarrior
StriplingWarrior

Reputation: 156624

It seems to me that it's going to be a lot of work setting up your stored procedures to do what you want them to do when they are called for each test, and you still end up with the speed problems that databases always present. I'd recommend you do one or both of the following instead:

  1. Use TypeMock, which has a powerful isolator tool. It basically changes your compilation to make it so that your unit test can mock even static methods.
  2. Instead of just unit tests, try creating "acceptance tests," which focus on mimicking a complete user experience: log in, create object, view object (verify object looks right), update object, view object again (ditto), delete object (verify object is deleted). Begin each of these tests by setting up all the objects you'll need for this particular test, and end by deleting all those objects, so that other tests can run based on an assumed starting state.

The first approach gives you the speed and mockability of true "unit" tests, whereas the second one allows you to exercise much more of your code, increasing the likelihood that you'll catch bugs, even in things like stored procedures.

Upvotes: 0

Sam Holder
Sam Holder

Reputation: 32946

if you want to use the DB in the tests and have everything be deterministic then you need each test to have its own DB, which means creating (and potentially populating) a new db for each test.

Depending on how your DB layer creates its connection this is feasible. I have done similar by generating a DB using localDb in test setup with a GUID for the name and then deleting the DB again at the end of the test in the tear down.

It ends up being reasonably slow (not surprisingly) but having the DBs created on a Ram disk drive helped with that.

This worked ok for empty dbs, that then had schemas created by EF, but if you need a fixed set of data in the DB then you might need to restore it from a backup in the setup of the test

Upvotes: 1

Related Questions