Skip to content

Instantly share code, notes, and snippets.

@rrgayhart
Last active July 26, 2024 14:01
Show Gist options
  • 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

@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.

@aarkerio
Copy link

I prefer Webmock, I feel it gives me more control over the tests.

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