Refactoring from Template Method to Strategy can reduce code duplication in unit tests

Ivan Moore has a great post “Replacing Inheritance with Composition” at his blog, that explains how when you refactor your code from using Template Method to using Strategy can reduce the code duplication in your unit tests and also make your tests simpler.

Both patterns, template method and strategy, try to solve the same problem. Both patterns allow to separate a “high level” algorithm from other algorithms that vary.

The template method design pattern is class based. This pattern has an abstract class that defines the high level algorithm. The abstract class has a set of abstract methods that provide hooks for the extending classes (concrete classes)to implement a specific algorithm.

In template method the high level algorithm is independent of the specific algorithms. On the other hand the specific algorithms (the concrete classes) depend on the abstract class because they extend it and cannot be used and tested without it.

So since the tests of the concrete classes also test the high level algorithm (the code in the abstract class), which is the same for all the concrete classes it is logical for these test to have code duplication. Also since the tests test both the high level algorithm and a specific algorithm they are more complex.

The strategy design pattern is object based. In strategy we have a class (context) that implements the high level algorithm. This class delegates the details (algorithms that vary) to an interface (strategy interface). To implement a specific algorithm you implement the strategy interface (concrete strategies).

In the strategy the high level algorithm is independent of the specific algorithms. Also the specific algorithms do not depend on the high level algorithm, they depend only on the strategy interface. So the they can be used and tested without the context class.

The test of the strategy code are different. Since the context class is not abstract and only depends on an interface (the strategy interface) the context class can be tested in isolation from the concrete strategies using a mock object. This makes the testing code simpler.

The concrete strategies can be tested independently of the context object (because they only depend on the strategy interface) so their tests are simpler and do not have the code duplication that appears in the tests of the concrete classes at the template method implementation.

To make the above more clear read Ivan Moore‘s article that I mentioned at the beginning of this post. You may also want to read this article by Robert C. Martin at about Strategy and Template Method.