Chapter 5. Simulating External Services

In Chapter 4, Setting Up and Cleaning Up, we learned how to manage external resources such as databases and web services. In this chapter, we'll learn more advanced techniques for managing external web services using the VCR gem, which allows us to record real HTTP requests and then replay them in our tests.

The importance of external web services

It is increasingly common for software to rely on external web services. These can be from a third party, such as the openweathermap.org API we saw in Chapter 4, Setting Up and Cleaning Up. However, we are likely to also interact with web services from within our own organization, or those that we have written ourselves. Not only do web services allow us to access external tools, such as weather info from openweathermap.org, they are also a popular approach to architecting applications within an organization. It is safe to say that an HTTP API is the default approach to exposing a service over a network today.

Dealing with external web services in tests can be challenging. By definition, these services are external, so we don't have as much, or any, control over how they behave, or how much support they offer for testing. As we saw in Chapter 4, Setting Up and Cleaning Up, we should try to avoid these external services in most tests, so we need to mock them. These mocks need to be realistic but also simple enough to manage. This is a fundamental trade-off, as the more realistic the mocks are, the closer they are to the actual service being mocked, requiring much more complexity.

For example, if we wanted to mock the OpenWeatherMap web service for just a few requests to return the same data every time, our mocks would be simple. However, there are countless requests that we could make to OpenWeatherMap for countless places all over the world. And, of course, the weather is always changing, so the same request would return different results at different times. Finally, there may be intermittent unexpected responses to certain requests, for example, when the service is down, or if there is an unexpected error retrieving weather data for a particular location. If we tried to deal with each of these situations in our mock service, we would soon have a lot of complex code that's just for tests. The bad thing about this is that our tests would be harder to understand, and the likelihood of mistakes in the mock code would increase. The testability of our system would not be improved in such a scenario unless we devoted a large amount of time to developing and maintaining the mocks.

In certain cases, such an intensive effort is justified, but most of the time, we would be better served by leveraging the real external web service. The idea is simple. We send a number of real requests to the external service, and record the responses along with the requests. In our tests, we can simply mock the response for a request by looking it up in our recordings. In case we don't find any recorded response for a request in our tests, we can either raise an error, or send a request to the real external service. If we wanted to make things very easy to maintain, we could have a script that updated all of our recordings on demand, allowing us to keep up with any changes to the responses of the external service. This way we would detect issues such as changed response formats and deprecated API endpoints.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset