
697
a Humble Object to move all of the controller and view-updating logic out of
the framework-dependent object and into a testable object.
Variation: Humble Executable
Many programs contain active objects. Active objects have their own thread of
execution so they can do things in parallel with other activities of the system.
Examples of active objects include anything that runs in a separate process (e.g.,
Windows applications in .exe fi les) or thread (in Java, any object that imple-
ments Runnable). These objects may be launched directly by the client, or they
may be started automatically, process requests from a queue, and send replies
via a return message. Either way, we must write asynchronous tests (complete
with interprocess coordination and/or explicit delays and Neverfail Tests; see
Production Bugs) to verify their behavior.
The Humble Executable pattern provides a way to bring the logic of the exe-
cutable under test without incurring the delays that might otherwise lead to Slow
Tests and Nondeterministic Tests. We extract all the logic from the executable into
a component that is testable via synchronous tests. This component implements
a service interface consisting of methods that expose all logic of the executable;
the only difference is that these methods are accessible via 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 Humble Executable component itself contains very little code. All it
does in its thread of control is to load the testable component (if a True Hum-
ble Object) and delegate to it. As a result, the Humble Executable requires
only one or two tests to verify that it performs this load/delegate function
correctly. Although these tests still take seconds to execute, they have a much
smaller impact on the overall test suite execution time because so few of them
exist. Given that this code will not change very often, these tests 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 the
Humble Executable tests as part of the automated build process.
Variation: Humble Transaction Controller
Many applications use databases to persist their state. Fixture setup with databases
can be slow and complex, and leftover fi xtures can wreak havoc with subsequent
tests and test runs. If we are using a Shared Fixture (page 317), the fi xture’s persis-
tence may lead to Erratic Tests. Humble Transaction Controller facilitates testing of
the logic that runs within the transaction by making it possible for the test to control
Humble Object
Humble
Object