Posted almost 10 years ago. Visible to the public. Repeats. Linked content.

Faking and testing the network with WebMock

An alternative to this technique is using VCR. VCR allows you to record and replay real HTTP responses, saving you the effort to stub out request/response cycles in close details. If your tests do require close inspection of requests and responses, Webmock is still the way.

WebMock is an alternative to FakeWeb when testing code that uses the network. You should probably learn it together with RestClient, which is an awesome alternative to net/http and shares many concepts with WebMock.

You can fake a remote server response like this:

stub_request(:get, 'http://host/api').to_return(:body => 'fake body')

You can test that a request has happened like this:

stub_request(:get, 'http://host/api').to_return(:body => 'fake body') RestClient.get('http://host/api') WebMock.should have_requested(:get ,'http://host/api')

Params are tricky

Testing for request params is a little tricky because Rails hides details about how HTTP works. In particular GET requests encode their params in the URL while POST, PUT and DELETE requests encode their params in the body. Neither WebMock nor RestClient will hide that from you (for reasons outside the scope of this article).

Compare stubbing a POST request with params...

stub_request(:post, 'http://host/api').with(:body => { :name => 'value' }).to_return(:body => 'fake body')

... to stubbing a GET request with params:

stub_request(:get, 'http://host/api?name=value').to_return(:body => 'fake body') stub_request(:get, 'http://host/api').with(:query => { :name => 'value' }).to_return(:body => 'fake body') # alternate way to write the above

Also compare expecting a GET request with params...

stub_request(:get, 'http://host/api').with(:query => { :key => 'value' }).to_return(:body => 'fake body') RestClient.get('http://host/api?key=value') RestClient.get('http://host/api', :params => { :key => 'value' }) # alternate way to write the above WebMock.should have_requested(:get ,'http://host/api?key=value') WebMock.should have_requested(:get ,'http://host/api').with(:query => { :key => 'value' }) # alternate way to write the above

... to expecting a POST request with params:

stub_request(:post, 'http://host/api').with(:body => { :key => 'value' }).to_return(:body => 'fake body')'http://host/api', :key => 'value') WebMock.should have_requested(:post ,'http://host/api')

Here is a way to test that certain query parameters are included in a request. This might come in handy if there are a lot of params or you are only interested in certain query params:

WebMock.should have_requested(:get, /http:\/\/host/api/). with(query: hash_including({ closed: 'true' }))

For this to work properly, make sure you've got WebMock >1.18.

Growing Rails Applications in Practice
Check out our new e-book:
Learn to structure large Ruby on Rails codebases with the tools you already know and love.

Owner of this card:

Henning Koch
Last edit:
14 days ago
by Julian
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more