Lesson Tuesday

In a previous lesson, we learned how to use VCR to stub our API calls. However, stubbing has many important use cases beyond testing HTTP calls. For instance, we can stub any method in our own code as well.

Stubs and Mocks


Here's an example. Let's say we're building a microservice (a modular piece of functionality within a larger application) that determines the cost of shipping widgets to Widgetville. However, there's another microservice being built that determines a widget's total weight. The second microservice hasn't been completed yet, so we need to stub or mock our tests so we can test our shipping-related code without having access to the microservice that determines the total weight of widgets. (More on mocks in just a moment.)

In this case, our stubs and mocks are placeholders for code that hasn't been written yet. We can't determine shipping without knowing the weight of our widgets, so we have to fake that data.

There are many other use cases where faking data is helpful or necessary. If you have a method in your application that takes a long time to run and has already been tested, there's no need to run the method again each time it's needed in other tests. Using a stub is more efficient. (This is exactly what we're doing with VCR.) Stubs and mocks can also help ensure that tests are less brittle (likely to break) when they're used correctly.

Stubs, mocks and other test doubles are an essential part of good testing and are universal to programming, not just to Ruby and Rails.

Wait a minute... what are test doubles? What's the difference between stubs and mocks, anyway?

Test Doubles

Let's start with test doubles. A test double is simply an object, method or procedure used in testing that is designed to mimic a similar object, method or procedure used in production. Stubs and mocks are both test doubles. There are other types, too, such as dummies and spies, but that's beyond the scope of this lesson.

Differences

Now let's briefly discuss the difference between stubs and mocks.

  • A stub returns a predetermined value. In the example of an API call with VCR, a stub will fake the response. The stub is a real object that represents what the API call should return, but it's not actually a response from the API itself.

  • A mock, on the other hand, would fake the API itself. The mock will approximate how we expect the real object (in this case, the API) to behave. In other words, mocks simulate the behavior of more complex objects so that we can in turn test that behavior.

The distinctions between mocks and stubs can be subtle, so don't worry if the differences aren't fully clear yet. Just know there's a wide world of testing out there beyond what we cover in this course.

Additional Resources


If you want to explore stubs and mocks further on your own, check out the documentation for webmock and rspec-mocks, which is built on rspec.

Terminology


  • A stub returns a predetermined value for a test. It's especially useful when a test takes a long time to run or uses up API calls, or when a piece of functionality hasn't been built out yet but should return a certain value.

  • A mock fakes the behavior of a real object, such as an API or service. In other words, it simulates the object's behavior.

  • A test double is an object, method or procedure used in testing that is designed to mimic a similar object, method or procedure used in production. Both stubs and mocks are test doubles.

Lesson 19 of 27
Last updated July 14, 2022