I promised I'd write something techie one of these days so here it is. It's a technique I've been using to write unit tests against code that has a problem with dependencies. Many times this is a third party system or a database with a variable data set that you can't write a good case against. Michael C. Feathers describes this as a Seam in Working Effectively with Legacy Code (a fantastic book -- buy it).
So let's say you have a class something like this...
public class Report {
public Integer[] fetchDataSet() {
Integer[] lDataSet = null;
// Go to the DB and fetch the data set (use your imagination here...lol)
return lDataSet;
}
public int sumDataSet() {
Integer[] lDataSet = fetchDataSet();
int sum = 0;
for (int i = 0; i < lDataSet.length; i++) {
sum += lDataSet[i].intValue();
}
return sum;
}
}
...and you need to write a test for the sumDataSet() method. Normally you would write a JUnit test something like this:
public void testSumDataSet() {
Report report = new Report();
int sum = report.sumDataSet();
assertFalse(sum == 0);
}
The two main problems with this is that it has a dependency on the database and you might not know what the values in the database are going to be so it's hard to make a proper assert. There may be some cases where a sum of 0 is a valid sum so the assert in the example isn't a valid assert.
Fortunately, this problem is easily solved. All you need to do is subclass your Report object and replace the fetchDataSet() method with one of your own that returns a set of known values. It looks like this:
public class ReportTest extends Report {
public Integer[] fetchDataSet() {
Integer[] dataSet = new Integer[2];
dataSet[0] = new Integer(1);
dataSet[1] = new Integer(5);
return dataSet;
}
}
Now you can write your test case like this:
public void testSumDataSetWithoutDB() {
Report report = new ReportTest();
int sum = report.sumDataSet();
assertTrue(sum == 6);
}
And voila!! A true test of your sumDataSet() method that has no dependencies and a set of known values you can write a true assert against. It's a real unit test! Yes!!
If you have any questions please refer to the Feathers book. Every group that has legacy code should have a copy of it. Buy it, read it, live it.
Thursday, January 04, 2007
Subscribe to:
Posts (Atom)