Tuesday, 10 April 2007

How to make unit testing from another project in .NET

There is a recurrent debate around the notion of unit testing: should we only test the contracts, the visible part? or should we test the "internal affairs" of our class?

In my opinion, the first proposition isn't enough.

Since our teams decided to write unit tests in separate .NET assemblies (because we do not deploy test code in production, but tested code ;-), I was forced to find a trick in order to be able to query the private state of tested objects, without breaking the encapsulation.

This trick is the .NET explicit interface implementation mecanism.

"An interface member that is explicitly implemented cannot be accessed from a class instance, but only if the class instance is cast into the given interface."

eg:

// Interface for testing purpose only,
// (we always use a name like:
// I<ClassToTestName>ForTesting)
public interface IBoyForTesting
{
bool AlreadySpentAdolescentCrisis {get;}
}

// The class to test
public class Boy : IBoyForTesting
{
private int age;
private bool alreadySpentAdolescentCrisis;

public int Age
{
get
{
return this.age;
}
}

// Explicit interface member implementation:
bool IBoyForTesting.AlreadySpentAdolescentCrisis
{
get
{
return this. alreadySpentAdolescentCrisis;
}
}

/*
...

*/
}


// Unit testing sample
int age = 20;
Boy aBoy = new Boy(age);

// The following commented line would produce
// compilation error because it try to access an
// explicitly implemented member

// bool isAdult = aBoy.AlreadySpentAdolescentCrisis;



// To test this "almost private" information, you can write:
Assert.IsTrue( ((IBoyForTesting)aBoy). AlreadySpentAdolescentCrisis );


With the .NET interface explicit implementation feature, you can test your classes from the outside, without too much having to break the encapsulation.

No comments:

Post a Comment