A lot of times your app will require an external source - whether you’re building a scraper, hitting an API, or just referencing a webpage.
External sources should be tested in isolation rather than directly. This prevents problems such as hitting API limits, connectivity dependence, and slower test suites amongst other things.
The WebMock gem is great at stubbing out external requests and we can manipulate it to return what is expected.
Here’s an example test for a browser feature:
First make sure to install rspec, webmock, and capybara to your gemfile and to require them in your spec_helper.
We’ll create a feature spec for browsing a web page:
Running our test should show us a WebMock error:
WebMock is awesome because it provides us a snippet we can use. Simply copy the above snippet and let’s paste it into our spec:
Running our specs again should give us this error:
Great, so WebMock is doing it’s job and blocking external requests. Now we have to tell it what to return instead. We can do this by replacing the body with whatever we’re requesting, in this case Matz’s wiki page.
Make sure you’re in the app directory and that you’ve created the spec/fixtures folder. Then we can use the terminal to get what we want:
That command will go into the fixtures directory, paste the html from Matz’s wiki into a new file and save it as matz.html, and lastly it’ll cd us back into our app’s root directory.
Now that we have Matz’s wiki page saved, we can reference it in our tests:
And with that our test should pass!
Things to consider
Our copy of Matz’s wiki can get out of sync if anyone were to his wiki in the future. This could later lead to failed tests.
In a large application, we’ll end up with a lot of copied external sources (html, json, etc). This could lead to a lot of maintenance overhead.
Thanks to thoughtbot for the original inspiration on this post.