Skip to content

Instantly share code, notes, and snippets.

@rrgayhart
Last active March 3, 2020 19:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rrgayhart/8b932186df0894adbb66 to your computer and use it in GitHub Desktop.
Save rrgayhart/8b932186df0894adbb66 to your computer and use it in GitHub Desktop.
Webmock vs VCR for Testing External Calls

This is an excellent post that explains a little bit behind the difficulty in testing external services https://robots.thoughtbot.com/how-to-stub-external-services-in-tests How to Stub External Services in Tests

One simple option is to use Webmock

Here is an example of using Webmock in a similar way to what VCR does - which is recording and reading from a file

stub_request(:any, "www.example.com").
  to_return(:body => File.new('/tmp/response_body.txt'), :status => 200)

So what you can do is throw a byebug in dev where you're making an api call and then write what you get from that api call to a file, using something like this:

File.open('/tmp/response_body.txt', 'w') { |f| f.puts 'abc' }

Only in this case you'd probably use a .json file

You can then mess up your api key and get an example of what a 500 status looks like and then input crap data and get what an example of a not-found or 404 status looks like Then you'll be prepared for the 'unhappy' path

This is an example of a VCR cassette

As you can see, it stores a lot of additional data But the way most people use them is just to provide the 'body' or a response and a status code Here is where the body is in a VCR

If that's all you need for testing, then I'd avoid VCR, personally.

I'd advocate for the 'file' approach to stubbing the API for some things - because you can very easily swap out files But with webmock you can also just pass a hash in your testing code Reading from files will add some time to how long your tests take to run - so limit the # of times you read a file by having it happen only once for a set of tests, if possible

@boddhisattva
Copy link

@rrgayhart This is a nice explanation of the differences between webmock and VCR, Thanks for sharing it :)

@diegommarino
Copy link

Thank you. This is a very interesting structure that you provided there.

@silva96
Copy link

silva96 commented Jan 21, 2020

I find webmock more lean than vcr, which adds a lot of unnecessary info for most of the use cases. Each tool has their own use though, if you want to do something more advanced probably VCR would suit better.

@yoelblum
Copy link

yoelblum commented Jan 30, 2020

Nice post. I think what's missing in the discussion is simply Rspec expectations. If you wanna mock your GithubClient's fetch method, a lot of the time you can simply
response = file_fixture('path_to_file_response')
expect(GithubClient).to receive(:fetch).and_return(response)

If you're already using Rspec this is quick and easy. So even Webmock could be an overkill.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment