Published June 28, 2020
by Doug Klugh
Method of Last Resort
Apply this pattern only as a last resort by modifying the System Under Test (SUT) to introduce test-specific behavior. This approach may be required in order to utilize test doubles when dynamic binding is not available. This pattern can be used to bring legacy code under test and provide a Safety Net to facilitate refactoring for even greater testability. These test hooks should be gradually removed as the system evolves into a loosely-coupled, flexible system.
A test hook can be easily added by inserting code into the SUT to direct control to a test double, create a test double within the real object, or apply the Decorator Pattern to add test-specific behavior during testing and delegate to the real object when running in production.
Preprocessor directives, compiler macros, or simple flags can be used to provide conditional compilation to include or exclude test-specific logic and may be used to remove the test hooks before the build is deployed to production.
When dynamic binding is available, promoting testability is better achieved using the Dependency Inversion Principle. This allows us to isolate the SUT and enable the substitution of test doubles in place of dependencies.