Problem

Get an overview of problems in Rails.

First problem

We have a problem. We want to add credit card processing to the project application so that we can make money. Testing the credit card functionality presents immediate difficulties. For one, we don’t want to make a credit card purchase during testing accidentally because that would be bad. But even if the purchase gateway provides a test sandbox, we still don’t want to depend on it for the unit tests to run. That network call is slow, and we don’t want the passing tests to depend on a remote server’s status.

Second problem

Or we might have a different problem. We’d like to build the code using a modular design. In doing so, we’d like the tests to be as isolated as possible from dependencies on other parts of the code. For example, we might have business logic that calls a model, but we want to test without depending on the model. We also want the workflow test to work even if the model is broken and the model code does not yet exist.

Solution

The solution to both problems above is a test double. A test double is a “fake” object used in place of a “real” object for automated testing. By “fake,” we mean that the object doesn’t have a real implementation but might instead have canned values that it can return in response to specific messages.

Uses of test doubles

Test doubles have multiple uses:

  • We can use a double when the real object is unavailable or difficult to access from a test environment.

  • We can use a double to create a specific application state that would otherwise be difficult to trigger in a test environment. Database or network failures, for example, might depend on program states that are non-deterministic or otherwise hard to replicate in testing.

  • Doubles can also be used strategically to limit a test’s execution to the object and method specifically under test or to specify an object’s interface or part of an object that does not yet exist.

  • Doubles can be used to support a different testing style, where the test verifies the system’s behavior during the test rather than the system’s state at the end of the test.

In this chapter

Test doubles can be a bit of a contentious issue, with different people giving conflicting advice about the best way to use them when testing. We want to give us enough information to make informed decisions about who to agree with. We’ll start by looking at the mechanics of test doubles using the rspec-mocks library. We’ll then discuss different ways to use doubles to solve both of the testing issues described at the start of this chapter. Later, in Minitest, we’ll cover the Mocha mocking library basics for use with Minitest.

Get hands-on with 1400+ tech skills courses.