Question

I've gotton to the point in my simple project where I'm ready to unit test the DAL.

I basically have a class called FooDataAccess with several very simple functions, lets say 3 of them like this:

int InsertFoo(string fooName)
void UpdateFoo(int fooID, string fooName)
void InsertFoosDepedency(int fooID, string someValue)

What I did was this - put 4 SQL Scripts inside my unit test project, the last one as am embedded resource.

1) Create (Unit test) Database Script, 2) Create Objects Script, 3) Insert Lookup Table Values and 4) Delete All But Lookup Table Values

The idea is, anyone first using the project should manually run scripts 1-3 by hand as a one-time setup. Then execute script #4 on start-up of each unit test... (in small apps, you could even run all of them at the testing level)

OK, so far so good...

So I have my unit test database setup, as an empty slate. Testing the first function InsertFoo() is obviously very simple. I call the function, then just Assert(ExecuteSQL("select count(*) from foo") > 1), Assert(ExecuteSQL("select fooName from t_foo") = expected)), etc..

Where I'm a bit stuck is the ones which require dependencies, like the 3rd function in my example, or even the update.

Would it make sense to temporarily drop all foreign key constraints for the scope of my test? Otherwise, in order to unit test the InsertFoosDepedency(int fooID, string someValue) function, I would have to execute some arbitrary sql first (manually insert a record to the FOO table and return the FooID)...

OR, should I just do the latter?

Any and all feedback is greatly appreciated.

UPDATE: Its working cleanly with inline SQL to create the dependents. I guess I'm just looking for comments & critisism on this method for unit testing DAL. Thanks again

Was it helpful?

Solution

This sounds quite similar to what I do. I destroy all the data in the database at the start of each test and then build up just what that test requires in that tests set up phase. So for UpdateFoo I would have

void update_existingKey_updatesValue() {
   String expected = "jeff";

   clearDatabase();
   // Note I would use dbUnit.
   executeSQL("insert into foo values (1, 'fred')");

   DAL subject = new DAL(...);
   subject.update(1, expected);  

   //Note I would use dbUnit.   
   String actual = executeSQL("select name from foo where id = 1"); 
   assert(expected, actual);
}

In Java I use a tool called dbUnit, your method names suggest C# so I'll point you at dbUnit.Net however I have never used this. This provides a nicer (IMO anyway) method of populating the database and verifying the content of the database.

OTHER TIPS

I would say never muck around with your schema for the sake of tests. If you fail to put it back or your code to put it back fails you'll find yourself in a mess very quickly.

Can you use Mock Objects?

If no, I think all you can do is set up database pre-reqs for each test.

You could consider a separate class for each test and use Setup and Teardown methods to get the database in the right condition for the tests.

Or you just have to do your test-specific setup in the Test method (and you could use Teardown to empty the DB afterwards).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top