Blog

Testing External Services Using VCR

Alina Developer portrait
Alina Karmacharya
December 13, 2023

While working with web development we often use external services in applications for making the application features rich, interactive and easy to use for users. But testing these external services is challenging at times. RSpec and VCR can help developers to test such interactions with external services effectively and confidently.

Testing External Services

It is important to test the external services to ensure following - Verify the flow the process is working properly - Prevents regression testing while there is change in external APIs - End to end testing and identify the issues in early development phase

What is VCR?

VCR is a Ruby gem for HTTP interactions and replay them during future test runs. It interacts with HTTP servers for the first time, captures it and replay it during future test runs for fast and accurate result. The use of VCR provides following benefits: - Avoid disruptions caused by external service outages - Speed up the testing - Achieve consistency in Testing

Setup and Configuration for RSpec and VCR

Step 1: Add necessary gems Add following in gemfile to install rspec and vcr.

ruby
# Gemfile
group :test do
 gem 'rspec-rails'
 gem 'vcr'
 gem 'webmock'
end

Run bundle install to install the gems. Webmock gem is used by VCR for the HTTP request mock.

Step 2: Configure RSpec and VCR

Execute rails generate rspec:install to generate the configuration file for RSpec. It will create spec/spec_helper.rb. Update spec/spec_helper.rb with following config to configure VCR.

ruby
# spec/spec_helper.rb
require 'vcr'

VCR.configure do |config|
  config.cassette_library_dir = 'spec/cassettes'
  config.hook_into :webmock
end

RSpec.configure do |config|
  config.before(:suite) do
    VCR.turn_on!
  end

  config.after(:suite) do
    VCR.turn_off!
  end
end

Example

Let’s go through weather API integration and test coverage for it.

Step 1: Create the Weather Service Class

Create a WeatherService class in app/services/weather_service.rb with following code:

ruby
# app/services/weather_service.rb
require 'net/http'
require 'json'

class WeatherService
  API_BASE_URL = 'https://api.weatherapi.com/v1/current.json'
  API_KEY = 'api_key'

  def initialize(city)
    @uri = URI(API_BASE_URL)
    @uri.query = URI.encode_www_form(key: API_KEY, q: city)
  end

  def current_temperature
    response = fetch_weather_data
    data = JSON.parse(response.body)
    data['current']['temp_c']
  end

  private

  def fetch_weather_data
    Net::HTTP.get_response(@uri)
  end
end

Step 2: Write spec for WeatherService

Create a spec file at spec/services/weather_service_spec.rb with following code:

ruby
# spec/services/weather_service_spec.rb
require 'rails_helper'
require 'weather_service'

RSpec.describe WeatherService, type: :service, vcr: true do
  describe '#current_temperature' do
    let(:city) { 'New York' }

    subject(:current_temperatue) do
      described_class.new(city).current_temperature
    end

    it 'fetches the current temperature using VCR' do
      VCR.use_cassette('current_temperature') do
        expect(temperature).to be_a(Float)
      end
    end
  end
end

Step 3: Run the Test

Execute rspec spec/services/weather_service_spec.rb to run the test.

VCR will record the HTTP interaction during the first run and use the recorded data for subsequent runs. The VCR.use_cassette records HTTP interactions during the first test run and replays them in subsequent runs. The cassette name (‘current_temperature’) represents the name of the file where the recorded interactions are stored. You can find the cassette for the above test in spec/cassettes/current_temperature.yml.

Conclusion

In this way we can leverage the advantage of VCR and RSpec to test the external service in an application. By isolating tests, speeding up test execution, and ensuring consistency, this combination provides developers with the confidence to build and maintain applications that interact seamlessly with external APIs or services. Happy Testing!!

Thanks for reading, no matter your software problem, we provide a complete solution to scope, design, develop, test, host, maintain and support it 24/7/365. Contact us to find out how can we bring your ideas to reality!