Wednesday, December 21, 2005

Unit testing reality

I has been a pleasure reading Roy Osherove's articles on unit testing. In "Write Maintainable Unit Tests That will Save You Time And Tears" he talks about some of the pitfalls of unit testing, the list is probably not complete, but I good read.

On a side-note: I feel that articles written with the intention of explaining shortcomings (scope) and pitfalls are much more educational then the ones simply explaining the usage. I felt this strongly when reading about Fitness where I had problems in figuring out its scope.

The other article, discussed unit testing database access layer code. It had the excellent suggestion of using COM+ 1.5 SWC to encapsulate the unit tests in transactions, thus ensuring independence between unit test. I am looking forward to following this suggestion.

Polymorphism and Interfaces

The following code did not behave as I expected. It returns "A::f" twice, but I expected it to return first "A::f", then "B::f".

There are two ways of getting the desired behavior, either declaring A.f() virtual or explicitly stating that B implements I. The latter is not desirable since I don't think B should need to know that A implements I, and the former I don't think is intuitive.

Any thoughts?

public interface I
{
void f();
}
public class A : I
{
public void f() { Console.WriteLine("A::f") ;}
}
public class B : A
{
public void f() { Console.WriteLine("B::f"); }
}
public class C
{
static void Main()
{
I i1 = new A();
I i2 = new B();

i1.f();
i2.f();
}
}

Thursday, December 01, 2005

Completing the design

The simple concept of refactoring has helped me allot. I have the tendency of not being able to start implementing before I think I have the design all figured out. This is something I think I got imprinted in school through all the "bugs-found vs. development-phase" graphs, and perhaps it is in my character as well :) Now I just tell myself: "this might not be perfect, but I will just refactor it later", and it does wonders for my throughput :)

I have in fact turned quite against completing the design before coding. In particular, I think that one should not try to guess how a particular class might be used in the future, e.g., by adding numerous accessor functions no one uses but need to be maintained and unit tested.