8

I have VCR set up and it runs on several tests I have written without issue. The most recent test I tried to write will pass the first time it is run, but will remain failing after that unless I delete the cassette. The code for the test is:

it "doesn't blow up if a user doesn't have billing info" do
    VCR.use_cassette('tax_reconciler/no_method_error')do
      user_guid = rand(10000000)
      CreateRecurlyTestData.create_account(user_guid, nil, nil)
      tax_reconciler = TaxReconciler.new
      new_tax_amount = rand(100000)
      user = create_test_user(:guid => user_guid)
      expect(tax_reconciler.update_tax_amount(user, new_tax_amount)).to_not raise_error
    end
  end

The error message is as follows:

Failure/Error: CreateRecurlyTestData.create_account(user_guid, nil, nil) VCR::Errors::UnhandledHTTPRequestError:

   ================================================================================
   An HTTP request has been made that VCR does not know how to handle:
     GET https://2b64d08ef45c446dbba75720a37b7d41:@api.recurly.com/v2/accounts/3276643

   VCR is currently using the following cassette:
     - /Users/Evan/dish/stallone/fixtures/vcr_cassettes/tax_reconciler/no_method_error.yml
     - :record => :once
     - :match_requests_on => [:method, :uri]

   Under the current configuration VCR can not find a suitable HTTP interaction
   to replay and is prevented from recording new requests. There are a few ways
   you can deal with this:

     * If you're surprised VCR is raising this error
       and want insight about how VCR attempted to handle the request,
       you can use the debug_logger configuration option to log more details [1].
     * You can use the :new_episodes record mode to allow VCR to
       record this new request to the existing cassette [2].
     * If you want VCR to ignore this request (and others like it), you can
       set an `ignore_request` callback [3].
     * The current record mode (:once) does not allow new requests to be recorded
       to a previously recorded cassette. You can delete the cassette file and re-run
       your tests to allow the cassette to be recorded with this request [4].
     * The cassette contains 4 HTTP interactions that have not been
       played back. If your request is non-deterministic, you may need to
       change your :match_requests_on cassette option to be more lenient
       or use a custom request matcher to allow it to match [5].

   [1] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/configuration/debug-logging
   [2] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/record-modes/new-episodes
   [3] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/configuration/ignore-request
   [4] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/record-modes/once
   [5] https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/request-matching

The only config options in spec helper are:

VCR.configure do |c|
    c.cassette_library_dir = 'fixtures/vcr_cassettes'
    c.hook_into :webmock # or :fakeweb
  end
ruby_newbie
  • 3,190
  • 3
  • 18
  • 29
  • 1
    You've basically pasted the source code for vcr (`vcr/vcr.rb`). Typically this is not what you mean by configuration. Are you doing some kind of weird overriding? Also: please post your actual errors. I think it sounds like you're just using the wrong recording mode. – Jesper Sep 12 '14 at 07:19
  • I updated with the error message and the config. My apologies but I thought that what I pasted earlier was the config. I guess my Username applies here. Thanks again. – ruby_newbie Sep 12 '14 at 16:30

1 Answers1

11

Your VCR setup is configured in recording mode :once: https://www.relishapp.com/vcr/vcr/v/1-8-0/docs/record-modes/once

In short, it only records requests when there is no cassette. For subsequent runs, it will only read the recorded requests, so a request that doesn't match any of the recorded requests will raise this error.

One common way for things to go wrong with this mode is if you delete your cassette and the only run one spec, instead of the whole suite. Bingo - your cassette is created and all requests except for the one in that particular spec will be unrecognized.

An upside to this mode is that you can catch spurious requests - if you know that your cassette contains all valid requests, you can catch bugs that are due to incorrect requests by using this mode.

If you want to be more flexible, you can use the recording mode new_episodes. In this mode, recognized requests will be replayed from the cassette, and unrecoqnized ones will be performed and recorded.

Jesper
  • 4,535
  • 2
  • 22
  • 34
  • For those having a similar problem the line that fixed this (and got me to the next error message) was "VCR.use_cassette('tax_reconciler/no_method_error', :record => :new_episodes )". Thanks for your help everyone. – ruby_newbie Sep 14 '14 at 13:27
  • 5
    Adding `:record => :new_episodes` bypasses the error but probably isn't what you want. You're using VCR to have fast, deterministic tests, but using `:record => :new_episodes` means that when VCR can't find a matching request, it'll allow the request and record it. That's fine if you've made a code change that triggers a new request, but in your case it sounds like it happens when you re-run your tests. VCR isn't able to match against a prior test, probably because your request is non-deterministic. On each test run are the `2b64d08ef45c446dbba75720a37b7d41` and `3276643` parts the same? – Myron Marston Dec 01 '14 at 00:12