Posts Tagged ‘mock objects’

Unit test stubs for code with “call chains”

Sunday, April 6th, 2008

What

Unit tests should be done in isolation. Many functions are dependent on other function to do some work. For these other functions we need stubs so that the function that is unit tested could be performed in isolation. So how this can be achieved without having to change the production code each time we want to unit test is explored in the following lines…

Why

To test the smallest unit possible as easy as possible. To be able to acomplish this we want to dynamically create the concrete implementation of our dependencies, see code example of how to this later on. 

And creating unit tests contribute to better and decoupled design of the software.

Where

In the solution and/or project to be unit tested.

When

When writing code and unit test.

Who

Insert interfaces between all the collaborators and create test stubs that implement these interfaces. E.g. if a function in a component/class is called by the function to be unit tested create an interface with this function and a stub that implements this interface. When the function is unit tested the stubs function is called instead of the original function. This way we have control over the result of that function and the unit test. So to sum it up, we use interface to be able to implement stubs.

 

Use dependency inversion principle to decouple the layers.

Use the Mock Object Pattern to create stubs and to simulate object that is not tested. 

Use the Broker/Provider Pattern to simplify implementation and unit test. Create a test provider for initial development and unit test. Create the real provider for system integration.

Use configurable implementation through an interface definition that both the actual provider and the stub provider implements. The behavior to run is configured in the configuration file of the broker. Another possible solution here is to use Factories to replace objects runtime that should not be tested with mock object.

How

Example of configuration settings in the configuration file:

Example of deciding and loading a provider dynamically:

The static LoadProvider method is implemented in an abstract class that inherits the IProvider interface (but do not implement the interface, just declares it abstract). Then the actual provider and the stub provider inherit this abstract class and implement the IProvider interface. This way the broker are decoupled from the provider and only have to deal with one class and not a class to create the provider and the provider. E.g. the provider is responsible for creating itself when the broker calls the static LoadProvider method which returns the right provider to use by the broker.

The design:

All these three components are separate projects that are compiled into their own assembly.

Reference

Agile Principles, Patterns, and Practices in C#, Robert C. Martin and Micah Martin, Prentice Hall, 2007.