Are you sure he said test to the interface and not program to the interface?
In very simple terms what program to an interface means is that your classes should not depend on a concrete implementation. They should instead depend on an interface.
The advantage of this is that you can provide different implementations to an interface, and that enables you to unit test your class because you can provide a mock/stub to that interface.
Imagine this example:
public class SomeClass{
StringAnalyzer stringAnalizer = new StringAnalizer();
Logger logger = new Logger();
public void SomeMethod(){
if (stringAnalyzer.IsValid(someParameter))
{
//do something with someParameter
}else
{
logger.Log("Invalid string");
}
}
}
Contrast that with this one:
class SomeClass
{
IStringAnalyzer stringAnalizer;
ILogger logger;
public SomeClass(IStringAnalyzer stringAnalyzer, ILogger logger)
{
this.logger = logger;
this.stringAnalyzer = stringAnalyzer;
}
public void SomeMethod(string someParameter)
{
if (stringAnalyzer.IsValid(someParameter))
{
//do something with someParameter
}else
{
logger.Log("Invalid string");
}
}
}
This enables you to write tests like this:
[Test]
public void SomeMethod_InvalidParameter_CallsLogger
{
Rhino.Mocks.MockRepository mockRepository = new Rhino.Mocks.MockRepository();
IStringAnalyzer s = mockRepository.Stub<IStringRepository>();
s.Stub(s => s.IsValid("something, doesnt matter").IgnoreParameters().Return(false);
ILogger l = mockRepository.DynamicMock<ILogger>();
SomeClass someClass = new SomeClass(s, l);
mockRepository.ReplayAll();
someClass.SomeMethod("What you put here doesnt really matter because the stub will always return false");
l.AssertWasCalled(l => l.Log("Invalid string"));
}
Because in the second example you depend on interfaces and not concrete classes, you can easily swap them by fakes in your tests. And that is only one of the advantages, in the end it boils down to that this approach enables you to take advantage of polymorphism and that is useful not only for tests, but for any situation where you may want to provide alternative implementations for the dependencies of your class.
Full explanation of the example above can be found here.