views:

83

answers:

3

As part of process improvements we are trying to ensure that all our projects have suitable unit tests, as there is a bit of education required in house I am trying ascertain what exactly is the best way to ensure we are making our classes as 'testable' as possible.

I suspect that we will start moving down the Mock object route and with most examples I have seen they interfaces to mock the implementations of the objects. So my question is should we ensure that ALL classes have an interface from which they derive?

If not what would be the process you would suggest in identifying classes that should have interface to allow them to be mocked?

+3  A: 

"identifying classes that should have interface to allow them to be mocked"

That doesn't seem all that hard. I'm not quite sure why you're asking. Perhaps you have other -- deeper -- questions.

You look at the design and find all pairs classes that are associated and ask "does A depend on B" if so, B must be mocked so A can be tested alone.

S.Lott
+5  A: 

No. Having interfaces on all classes / objects will only create an unnecessary overhead without producing any extra benefit.

The general rule of thumb is that your classes should depend on abstractions rather than concrete implementations, so I would suggest using "dependencies" as a starting point and any class that is an external dependency to another class should implement an interface.

lomaxx
+2  A: 

YAGNI says don't until you need it. I say: if you are using Test Driven Design, then I think you should use let the tests dictate the design.

As a concrete example, I am writing a virtual machine that can run an embedded bytecode. The interface to the outside world is the Runtime interface. The client uses it to run functions by name, query globals, and so on.

The implementation of the Runtime requires many different components, one of which is a VirtualMachine, which controls access to the stack, memory, registers and the like.

When Unit Testing, the idea is to take each object and test it in isolation from the rest of the world. However, the Runtime is dependant on the VirtualMachine. To detach the VM from the Runtime, it must be mocked. That means that VirtualMachine must derive from an interface common with MockVirtualMachine.

Therefore, the tests dictate that VirtualMachine should be inherited from an interface. I didn't need to do so until then.

Kaz Dragon