At first, sorry for my English :)
I need to realize API controller's tests in Ruby on Rails application (v 4.2.0). When I do request to GET Advertising Sources I have a json response like this:
{"advertising_sources":[{"id":59,"title":"accusantium"},{"id":60,"title":"assumenda"}]}
JSON response template was defined by front-end developer. Now I trying to create tests for: 1. JSON size (2 advert sources) 2. included attributes (id, title)
My tests:
it 'returns list of advertising sources' do
expect(response.body).to have_json_size(2)
end
%w(id title).each do |attr|
it "returns json with #{attr} included" do
hash_body = JSON.parse(response.body)
expect(hash_body).to include(attr)
end
end
Failures:
1. Failure/Error: expect(response.body).to have_json_size(2)
expected {"advertising_sources":[{"id":59,"title":"accusantium"},{"id":60,"title":"assumenda"}]} to respond to `has_json_size?`
2. Failure/Error: expect(hash_body).to include(attr)
expected {"advertising_sources" => [{"id" => 71, "title" => "necessitatibus"}, {"id" => 72, "title" => "impedit"}]} to include "id"
Diff:
@@ -1,2 +1,2 @@
-["id"]
+"advertising_sources" => [{"id"=>71, "title"=>"necessitatibus"}, {"id"=>72, "title"=>"impedit"}],
Can anyone help me to correctify my tests code? Thanks!
Given the shape of your response and the characteristics you are interested in testing, you can write your tests as follows:
describe 'advertising_sources' do
let(:parsed_response_body) { JSON.parse(response.body) }
let(:advertising_sources) { parsed_response_body['advertising_sources'] }
it 'returns list of advertising sources' do
expect(advertising_sources.size).to eq(2)
end
%w(id title).each do |attr|
it "returns json with #{attr} included" do
advertising_sources.each { |source| expect(source.keys).to include(attr) }
end
end
end
I would personally simplify this even further to:
describe 'advertising_sources' do
let(:parsed_response_body) { JSON.parse(response.body) }
let(:advertising_sources) { parsed_response_body['advertising_sources'] }
it 'returns list of advertising sources' do
expect(advertising_sources.size).to eq(2)
end
it 'includes an id and title for each source' do
advertising_sources.each { |source| expect(source.keys).to match_array(%w(id title)) }
end
end