Conflicting WebMock and VCR

Josua Schmid
2 min readAug 12, 2019

--

Who gets the HTTP request? – Photo by Chris Sabor on Unsplash

For a long time I used the Ruby gem WebMock to stub out HTTP requests in my test suites. It allows you to fine-tune what requests go out and what (fake) answers come in:

expect(WebMock).to have_requested(:get, "www.example.com").
with(body: "abc", headers: {'Content-Length' => 3}).twice

Another gem called VCR allows you to do similar things but on a much higher level. You basically record real HTTP requests from your test into a text file and replay this recording afterwards. You can even set an expiration date for the recording to make sure, that from time to time real working requests are made. This is pretty cool for very complex requests where you don’t want to tune it yourself with WebMock:

context 'when the hub room exists (default case)',
vcr: { cassette_name: 'broadcasting' } do
before { … busines logic for broadcasting }

it { is_anticipated.to change {
BroadcastMessage.delivery_due.count }.by(-1) }
end

Since there are some costs using VCR you may want to stick to WebMock for the simpler tests. But it turns out that it’s not so easy to run them both in the same setup because it’s not clear which library should hook into the requests. I for now make it explicit with the following RSpec setup code:

config.before(:each) do |example|
if example.metadata[:vcr]
VCR.turn_on!
else
VCR.turn_off!
end
end

This makes sure that VCR is turned on for flagged tests like the one above and turned off for the others which then fallback to WebMock.

--

--

Josua Schmid
Josua Schmid

Written by Josua Schmid

I engineer software and craft beer, or the other way around. Find my old blog here: https://web.archive.org/web/20181108025110/http://blog.schmijos.ch/

Responses (1)