Chapter 3. Using stubs to break dependencies

 

This chapter covers

  • Defining stubs
  • Refactoring code to use stubs
  • Overcoming encapsulation problems in code
  • Exploring best practices when using stubs

In the previous chapter, we wrote our first unit test using NUnit and explored the different testing attributes that are available, such as [ExpectedException], [SetUp], and [TearDown]. We also built tests for simple use cases, where all we had to check on were simple return values from simple objects.

In this chapter, we’ll take a look at more realistic examples where the object under test relies on another object over which we have no control (or which doesn’t work yet). That object could be a web service, the time of day, threading, or many other things. The important point is that our test can’t control what that dependency returns to our code under test or how it behaves (if we wanted to simulate an exception, for example). That’s when we use stubs.

3.1. Introducing stubs

Flying people into space presents interesting challenges to engineers and astronauts, one of the more difficult being how to make sure the astronaut is ready to go into space and operate all the machinery. A full integration test for a space shuttle would require being in space, and that’s obviously not a safe way to test astronauts. That’s why NASA has full simulators that mimic the surroundings of a space shuttle’s control deck, which removes the external dependency of having to be in outer space.


Definition

3.2. Identifying a filesystem dependency in LogAn

3.3. Determining how to easily test LogAnalyzer

3.4. Refactoring our design to be more testable

3.5. Variations on refactoring techniques

3.6. Overcoming the encapsulation problem

3.7. Summary