Refactoring: Extract Testable ComponentThe book has now been published and the content of this chapter has likely changed substanstially.
Also known as: Sprout Class[WEwLC]
You want to be able to test the logic easily but the component is too closely tied to its context to allow this.
Extract the logic you want to test into a separate component that is designed for testability and is independent of the context in which it is run.
We extract all the logic from the untestable component into a component that is testable via synchronous tests leaving behind all the ties to the context. This usually means that anything required by the testable component logic from the context is retrieved by the the untestable component and passed in to the testable component as parameters of the methods under test or constructor methods. The untestable component then contains very little code and is now considered to be a Humble Object (page X). All it does is to retrieve the information the testable component requires from the context, instantiate the testable component and delegate to it. All interactions with the new testable component consist of synchronous method calls.
The testable component may be a Windows DLL, a Java JAR containing a Service Facade[CJ2EEP] class or some other language component or class that exposes the services of the executable in a testable way. The untestable code may be an executable, a dialog box or other presentation component, logic that is executed inside a transaction, or even a complex test method. Extraction of the testable component should leave us with a Humble Object that requires very little, if any, testing.
Depending on the nature of the untestable component we may choose to write tests for the delegation logic or we may be unable to do so because it is so closely tied to the context. If we do write tests for it, we require only one or two tests to verify it does the instantiation and delegation correctly. Since this code is not going to change very often, these tests are much less critical than the tests we have enabled ourselves to write. can even be omitted from the suite of tests that developers execute before check in to speed up test suite execution times. Of course, we would still prefer to run them from the automated build process.
This refactoring is similar to Extract Interface[Fowler] refactoring and Extract Implementer[Fowler] refactoring except that Extract Testable Component does not require keeping the same interface. It can also be viewed as a special case of the Extract Class[Fowler] refactoring.
Copyright © 2003-2008 Gerard Meszaros all rights reserved