When you write tests for your JSON API with request spec, typical code is like:
describe 'POST /restaurants' do
let(:params) { { name: 'pizza foobar' } }
it 'creates a restaurant' do
post '/restaurants', headers: headers, params: params
expect(response).to have_http_status(:created)
expect(response.parsed_body).to match(
'id' => String,
'name' => 'pizza foobar'
)
end
end
But this doesn't test the API right, technically.
Because this test sends a POST request with application/x-www-form-urlencoded
, not application/json
.
Mostly, you expect request body with application/json
for JSON API. This code does not simulate requests properly.
So, use as: :json
option:
post '/restaurants', headers: headers, params: params, as: :json
I'm lazy enough to avoid passing as: :json
every time.
Usually I override those helpers to pass as: :json
option by default:
module RequestHelper
%i[get post patch put delete].each do |method_name|
define_method(method_name) do |path, args = {}|
default_options = { as: :json }
process method_name, path, default_options.merge(args)
end
end
end
RSpec.configure do |config|
config.include RequestHelper, type: :request
# ...
Top comments (2)
Interesting solution! I can also propose to do it in that way dev.to/haukot/test-rails-api-with-... - we don't need to redefine our methods in it.
This post is about request specs.