Last active
August 29, 2015 14:11
-
-
Save hisapy/5d5b04aa894f21e15788 to your computer and use it in GitHub Desktop.
RSpec: call VCR registered request matcher from inside custom matcher
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# This is an excerpt from a spec_helper file with a section to configure VCR | |
# | |
# In lines 30 and 32 you can see examples of how to call a VCR registered request matcher from inside another. | |
# This is useful when running an example that makes a request to multiple external resources or APIs. | |
# Without this the requests were recorded the 1st time but subsequent requests raised VCR::Errors::UnhandledHTTPRequestError | |
VCR.configure do |c| | |
c.ignore_localhost = true | |
c.cassette_library_dir = 'spec/cassettes' | |
c.hook_into :webmock | |
c.allow_http_connections_when_no_cassette = false | |
c.configure_rspec_metadata! | |
#Custom Matchers | |
c.register_request_matcher :w3_css_validator, &VCR.request_matchers.uri_without_params(:output, :profile, :text) | |
c.register_request_matcher :s3_paperclip do |r1, r2| | |
#these .match might not be needed | |
r1_path = URI(r1.uri).path.match("#{CONFIG[:amazon][:s3][:bucket]}/").to_s | |
r2_path = URI(r2.uri).path.match("#{CONFIG[:amazon][:s3][:bucket]}/").to_s | |
if URI(r1.uri).host != "s3.amazonaws.com" || !r1_path | |
false | |
else | |
URI(r1.uri).host == URI(r2.uri).host && r1_path == r2_path | |
end | |
end | |
c.register_request_matcher :css_validator_and_s3_requests do | r1, r2| | |
if URI(r1.uri).host == "jigsaw.w3.org" | |
VCR.request_matchers[:w3_css_validator].callable.call(r1, r2) | |
elsif URI(r1.uri).host == "s3.amazonaws.com" | |
VCR.request_matchers[:s3_paperclip].callable.call(r1, r2) | |
end | |
end | |
end |
Thanks for taking your time to comment on this gist Myron. I'm using record: :once
and have been using :w3_css_validator
and :s3_paperclip
separately before creating the :css_validator_and_s3_requests
to handle requests of a model that queries those APIs at the same time. I'll read your suggestions carefully and see if I can simplify these requests matching logic.
Thanks a lot again.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In general yes -- I've used VCR many, many times where it made multiple requests to multiple external APIs from a single acceptance test that all recorded it into one VCR cassette. For your specific case, it's hard to provide a suggestion for a better approach without digging into the specifics of the requests that get made in by your test suite and what parts of those requests are non-deterministic. I honestly don't have the time to dig into that kind of detail (unless you want to pay for my time), but here are a few general suggestions:
uri_without_params
matcher is completely safe to use on requests which do not have the named parameters (URIs that lack those params will be compared unmodified). So unless your test suite has some requests that are made withoutput
,profile
ortext
query params where you don't want to ignore them, there's really no reason to apply that matcher only to "jigsaw.w3.org" requests.match_requests_on: [lambda { |r1, r2| true }]
: such a request matcher would consider any request to match any other request, even if they had nothing common. As bad as an idea as that is, it could actually work fine for tests that make the requests in a consistent, deterministic order.:new_episodes
record mode in these sorts of situations is also potentially problematic, because when a new, unmatched request is made, VCR will append that interaction to the end of the cassette, even if it's a new request from the start or middle of the test -- and then when playback happens on the next test run it could replay the wrong response for a request. It's better to use the:once
record mode as it only allows a cassette to be recorded once, preventing out-of-order-requests from being appended later.Good luck!