Search code examples
ruby-on-railsrspec-railsvcr

Custom VCR request matching options for some specific RSpec tests


I have a bunch of RSpec tests in my Rails project that test HTTP calls to external REST API and use VCR cassettes to record requests and respondes. Currently my VCR configuration is the following:

VCR.configure do |c|
  c.cassette_library_dir = 'spec/vcr_cassettes'
  c.hook_into :webmock
  c.configure_rspec_metadata!
end

So request matching rule matches only on HTTP method and URI. I want to change this setting to also match request body:

VCR.configure do |c|
  c.cassette_library_dir = 'spec/vcr_cassettes'
  c.hook_into :webmock
  c.configure_rspec_metadata!
  c.default_cassette_options = {
    :match_requests_on => [:uri, :method, :body],
  }
end

but since I already have a lot of tests in my project, I would like to do it gradually, activating this new restriction only to some of the tests, so the other ones (with old cassettes) would't break.

Is there any way to pass a parameter to RSpec tests to have a custom request matching rule only for some specific tests or groups of tests?

I imagine something like

it 'reverts transaction', :vcr, :body_matching => true do
    # something
end

and then change settings dynamically according to body_matching parameter.


Solution

  • The :vcr metadata can be set to a Hash of options which will be used for the inserted cassette. Therefore you could do

    it 'reverts transaction', vcr: { :match_requests_on => [:uri, :method, :body] } do
      # something
    end
    

    To make it nicer you could assign that hash to a variable and then just set that to the :vcr option. If you wan to go further than you'd need to create your own RSpec before/after set keyed off your own metadata name and then not include :vcr in the metadata (since you will need to do your own (insert_cassette) call). See https://github.com/vcr/vcr/blob/31e2cba76c0c9a60c3de5d5ece1c87563bfeacf7/lib/vcr/test_frameworks/rspec.rb#L32 for the before/after hooks VCR installs.