Project

rack-vcr

0.03
No commit activity in last 3 years
No release in over 3 years
This Rack middleware records incoming Rack request and responses in a VCR compatible format.
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
 Dependencies

Development

>= 1.10
~> 0.6
>= 10.0
>= 0
>= 1.4

Runtime

>= 2.9
 Project Readme

Rack::VCR

Rack::VCR captures incoming HTTP requests and responses on your Rack application (Rails, Sinatra) and saves them as a VCR fixture in cassettes.

Installation

Add this line to your application's Gemfile:

gem 'rack-vcr'

And then execute:

$ bundle

Or install it yourself as:

$ gem install rack-vcr

Usage

Capturing in Rails

In config/initializers/rack_vcr.rb:

if Rails.env.test?
  Rails.configuration.middleware.insert(0, Rack::VCR)
end

In spec/spec_helper.rb:

VCR.configure do |config|
  config.cassette_library_dir = 'doc/cassettes'
end

RSpec.configure do |config|
  config.around(:each, type: :request) do |example|
    host! "yourapp.hostname"
    name = example.full_description.gsub /[^\w\-]/, '_'
    VCR.use_cassette(name, record: :all) do
      example.run
    end
  end
end

The above example might not work if you were using RSpec 2.x, in which case you might need to write as follows:

RSpec.configure do |config|
  config.around(:each, type: :request) do |ex|
    host! "yourapp.hostname"
    name = example.full_description.gsub /[^\w\-]/, '_'
    VCR.use_cassette(name, record: :all) do
      ex.run
    end
  end
end

Read more about the changes around example on RSpec blog post.

Capturing in Sinatra/Rack

In spec/spec_helper.rb:

require 'rack/test'

VCR.configure do |config|
  config.cassette_library_dir = "vcr_cassettes"
end

describe 'My Web App' do
  include Rack::Test::Methods

  let(:app) {
    Rack::Builder.new do
      use Rack::VCR
      run Sinatra::Application
    end
  }

  it 'runs the request' do
    VCR.use_cassette('hello', record: :all) do
      get "/hello"
    end
    # Now you get vcr_cassettes/hello.yml saved
  end
end

Replaying

Rack::VCR also supports replaying recorded VCR cassettes. It means you can record the HTTP interactions with the real app (on CI), then use the cassette to run a fake/mock API server using Rack::VCR!

To replay cassettes, enable Rack::VCR with :replay option in config.ru or its equivalent.

VCR.configure do |config|
  config.cassette_library_dir = "/path/to/cassettes"
end

Rack::Builder.new do
  use Rack::VCR, replay: true,
    cassette: "test", record: :new_episodes
  run MyApp
end

With the above setting, Rack::VCR will try to locate the cassette named "test" to replay if the request matches with what's recorded, and fall through to the original application if it's not there. It also records the result to the cassette for further requests with the :record option set to :new_episodes.

You can set :record option to :none for example, to only serve what's already recorded in the cassette. The default value for :record option is :new_episodes.

To customize the cassette name in runtime, you can write a custom piece of Rack middleware around Rack::VCR to wrap the application in VCR.use_cassette with its own :record option.

class CassetteLocator
  def initialize(app)
    @app = app
  end
  
  def call(env)
    cassette = ... # determine cassette from env
    VCR.use_cassette(cassette, record: :none) do
      @app.call(env)
    end
  end
end

Rack::Builder.new do 
  use CassetteLocator
  use Rack::VCR, replay: true
  run MyApp
end

Notes

There's a few similar gems available on Rubygems and GitHub:

  • VCR::Middleware::Rack - Records outgoing HTTP requests inside a Rack application. Quite opposite to what Rack::VCR gem does.
  • rack-recorder - Essentially the same with Rack::VCR, but is very limited in what it does. It doesn't export the captured transaction in VCR compatible format.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/miyagawa/rack-vcr.

Author

Tatsuhiko Miyagawa

License

The gem is available as open source under the terms of the MIT License.