Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

The Legacy Code Dilemma

When we change code, we should have tests in place. To put tests in place, we often have to change code.

Sensing and separation.

Why do we need to break dependencies in our code base in order to implement effective unit tests?

  1. To separate the code we want to put under unit test from other dependencies that make it impossible/extremely difficult to run under the test harness. Example: A web application bein dependent on the Java servlets API makes it difficult to instantiate the servlets in our test environment without a web container.
  2. To sense the effects of our code on other components in the system. Using the same example of a web application, our tests are going to need to inject certian HTTP requests into the component under test and detect if certian responses are emitted. We might do this by creating a wrapper around our application that provides a simplified interface to substitute for HttpServletRequest and HttpServletResponse.

Fake objects - A way to substitute dependencies that can't be instantiated in the test environment for a facsimile that emulates the behavior of the dependency sufficient for the test. Fake objects also allow us to sense the effects of our code under test.

  • Fake objects can break the rules of good design. Use public properties and methods to make it easy to set and retrieve values from test code.
  • Fake objects are not as sophisticated as full-blown mock objects. Mocks provide a more complete simultation of the object being substituted and have the built in ability to set assertions for acceptable interactions from the test code. Mocking frameworks exist for most OO languages and can be quite useful, however simple fake objects will be acceptable in most situations.

A structured way to change legacy code

...