22 IEEE SOFTWARE May/June 2002 0740-7459/02/$17.00 © 2002 IEEE
O
ne thing that makes unit-testing code
so hard is the way the real world
keeps intruding. If all we had to do
was code up tests for methods that
sort arrays or generate Fibonacci se-
ries, life would be easy. But in the real
world we have to test code that uses data-
bases, communications devices, user inter-
faces, and external applications. We might
have to interface to devices that aren’t yet
available or simulate network errors that are
impossible to generate locally. This all con-
spires to stop our unit tests from being neat,
self-contained (and orthogonal) chunks of
code. Instead, if we’re not careful, we find
ourselves writing tests that end up initializ-
ing nearly every system component just to
give the tests enough context to run. Not
only is this time consuming, it also intro-
duces a ridiculous amount of coupling into
the testing process: someone changes an in-
terface or a database table, and suddenly the
setup code for your poor little unit test dies
mysteriously. Even the best-intentioned de-
velopers become discouraged after this hap-
pens a few times. Eventually, testing starts to
drop off, and we all know where that leads.
Fortunately there’s a testing pattern that
can help. Using mock objects, you can test
code in splendid isolation, simulating all
those messy real-world things that would
otherwise make automated testing impossi-
ble. And, as with many other testing prac-
tices, the discipline of using mock objects
can improve your code’s structure.
An example: Testing a servlet
Servlets are chunks of code that a Web
server manages. Requests to certain URLs
are forwarded to a servlet container (or man-
ager) such as Jakarta Tomcat (http://jakarta.
apache.org/tomcat), which in turn invokes
the servlet code. The servlet then builds a re-
sponse that it sends back to the requesting
browser. From the end user’s perspective, it’s
just like accessing any other page.
Figure 1 shows part of the source of a
trivial servlet that converts temperatures
from Fahrenheit to Celsius. Let’s quickly
step through its operation. When the servlet
container receives the request, it automati-
cally invokes the servlet method doGet(),
passing in two parameters, a request and a
response. (These are important for our test-
ing later). The request parameter contains
information about the request; the servlet’s
job is to fill in the response. The servlet’s
body gets the contents of the field “Fahren-
heit” from the request, converts it to Cel-
sius, and writes the results back to the user.
The writing is done via a PrintWriter object,
which a factory method in the response ob-
ject provides. If an error occurs converting
the number (perhaps the user typed “boo!”
software construction
Mock Objects
Dave Thomas and Andy Hunt
Editors: Andy Hunt and Dave Thomas ■ The Pragmatic Programmers
andy@pragmaticprogrammer.com ■ dave@pragmaticprogrammer.com
Yet sit and see; Minding true things by what their mockeries be. —Shakespeare, Henry V