In Part 2 of Automating Unit Tests with a Base Class I provided a set of example tests for CRUD operations. Although the logic is correct the implementation...kinda....well....sucks! The main problem is that many of the tests are dependent on functionality that is not directly being tested within the test method. As an example let's look at the CanBeRead() test...
1 public void CanBeRead() {
2
3 Customer savedCustomer = new Customer();
4 // ...set properties
5
6 Assert.IsTrue(savedCustomer.Save());
7
8 // read the customer
9 Customer readCustomer = new Customer();
10 readCustomer.Load(savedCustomer.CustomerID);
11
12 // check properties of the loaded object against the saved object
13 Assert.AreEqual(savedCustomer.ContactName, readCustomer.ContactName, "ContactName properties are not equal.");
14 Assert.AreEqual(savedCustomer.ContactTitle, readCustomer.ContactTitle, "ContactTitle properties are not equal.");
15 Assert.AreEqual(savedCustomer.Address, readCustomer.Address, "Address properties are not equal.");
16
17 // check remaining properties as necessary...
18 }
In order to test the “read“ of the object the test first calls the .Save() method on the customer object. If the .Save() method fails we get a failure for that test and will quickly assume our read logic is incorrect. Unfortunately by including the .Save() within the read test we get an inaccurate view into what is causing problems within our application. A better approach is to manually insert the records using a SQL statement. This prevents a failure in the .Save() from crashing our read test and ensures our tests only fail for a single reason.
So why did I present the test this way? Believe it or not I'm actually using code very similar to this in my test projects. Rather then calling INSERT's to place my test data in my database I'm using the .Save() method on my objects. This allows me to quickly test my objects and also makes the base unit test which I'm sure you are all anxiously awaiting easier to implement. Perhaps after I present my solution to automating the unit tests for CRUD operations I can clean the code up and implement a base test class that uses SQL statement to perform the necessary population and removal of test data.
Have I lost all my TDD/Unit Testing “street cred” by coming out of the closet and admitting to this heinous crime? :-(