Thursday, May 22, 2008

A New xUnit Test Pattern

Inspired by the Gerard Meszaros book xUnit Test Patterns: Refactoring Test Code, I have written down a pattern, which I used already many times:

Own Library Interface

Also known as: 'Skin and Wrap the API' [Working Effectively with Legacy Codeby Michael Feathers]

How can we make a code testable, when the code depends on a library class, which can't be replaced by a 'Test Double'?

We write our own interface that exactly mirrors the API of the library class. In our system under test (SUT) we use the interface instead of the library class itself.

The code we want to test is the system under test (SUT). It references a depended-on component (DOC) library class.

Some library classes do not inherit from an interface, they do not declare their methods as virtual or they provide static methods, so it is not possible to introduce a Test Double to the SUT via Dependency Injection or Dependency Lookup to replace the library class during testing. This problem arises very often when we need to use system or third party libraries (like the .NET framework) where we can’t modify the library classes and have to use them as they are. Library designers prefer to use class-based APIs instead of interfaces, because they can be evolved in later versions of the library. If they want to add members to a library interface in a later version , they would break existing code [Framework Design Guidelines: Conventions, Idioms, and Patterns for Reusable .NET Librariesby Abrams and Cwalina]. Very often the SUT can’t be tested together with the library class, because the library class can’t be used in the test environment. The reason may be that the library class will not return values needed for the test or executing it would have undesirable side effects.

How it Works

We write our own interface which mirrors the API of a library class we are using in our SUT. Our own interface does not need to contain the complete API of the library class but may contain only the subset we are requiring for our SUT. We implement a thin wrapper for the library class which inherits from our own interface. The wrapper will contain no logic. Each method can simply be forwarded to the library class, because the signatures of our own interface are the same as the library class. The SUT must use the interface instead of the library class itself. The SUT will be initialized with a concrete object via Dependency Injection or Dependency Lookup. In the production environment the thin wrapper is used. In the test environment we can replace the thin wrapper with a Test Double.

When to Use It

We have to use the Own Library Interface when we use a third party library class in our SUT which has both of the two following characteristics:
  • The dependency on the library class prevents us from executing the SUT in a test environment. It may be plain impossible, too slow, too complex or too expensive to prepare a test environment for testing the SUT together with the library class.
  • The library class can not be replaced by a Test Double, because it does not inherit from an interface, it does not declare its methods as virtual or it has static methods.
These circumstances very often lead to the smell Developers Not Writing Tests. The SUT will be declared as untestable. Also TDD beginners often stumble over this problem and get the impression that TDD is not applicable to real world examples.

Implementation Notes

Library classes which define the API for operating system mechanisms (registry, event log, services), the API for hardware sub systems (network infrastructure) or the API to other software components (SMTP server, POP3 server) are candidates for the usage of the Own Library Interface pattern. Preparing a fixture for testing own classes which are using such library classes may be plain impossible, too slow, too complex or too expensive. See TDD for Beginners as an detailed example for the usage of the Own Library Interface pattern. We do not need to use the Own Library Interface pattern, when we can test our SUT together with the library class. For example the File or Directory classes from the .NET framework can easily be tested together with the SUT, because preparing files and directories during test setup as well as checking them after exercising the SUT is quite easy.