How do I create an rspec test that validates a JSON response?
I have a Groups Controller with a method def inbox.
If the user is a group member then inbox returns a JSON object.
If the user is not a member, then inbox should redirect thanks to CanCan permissions.
How do I write an rspec to test these two use cases?
Current spec:
require 'spec_helper'
describe GroupsController do
include Devise::TestHelpers
before (:each) do
@user1 = Factory.create(:user)
@user1.confirm!
sign_in @user1
@group = Factory(:group)
@permission_user_1 = Factory.create(:permission, :user => @user1, :creator_id => @user1.id, :grou开发者_开发问答p => @group)
end
describe "GET inbox" do
it "should be successful" do
get inbox_group_path(@group.id), :format => :json
response.should be_success
end
end
end
Routes:
inbox_group GET /groups/:id/inbox(.:format) {:controller=>"groups", :action=>"inbox"}
Routes File:
resources :groups do
member do
get 'vcard', 'inbox'
end
....
end
This is how I do this:
describe "GET index" do
it "returns correct JSON" do
# @groups.should have(2).items
get :index, :format => :json
response.should be_success
body = JSON.parse(response.body)
body.should include('group')
groups = body['group']
groups.should have(2).items
groups.all? {|group| group.key?('customers_count')}.should be_true
groups.any? {|group| group.key?('customer_ids')}.should be_false
end
end
I'm not using cancan, therefore I cannot help with this part.
Sometimes it might be good enough to verify if response
contains valid JSON and to show actual response otherwise, here is an example:
it 'responds with JSON' do
expect {
JSON.parse(response.body)
}.to_not raise_error, response.body
end
Try this:
_expected = {:order => order.details}.to_json
response.body.should == _expected
I think the first thing you want to do is to check that the response is of the correct type, i.e. that it has the Content-Type
header set to application/json
, something along the lines of:
it 'returns JSON' do
expect(response.content_type).to eq(Mime::JSON)
end
Then, depending on your case, you might want to check whether the response can be parsed as JSON, like wik suggested:
it 'responds with JSON' do
expect {
JSON.parse(response.body)
}.to_not raise_error
end
And you could merge the above two into a single test if you feel like two tests for checking JSON response validity are too much.
To assert JSON you can do this too:
ActiveSupport::JSON.decode(response.body).should == ActiveSupport::JSON.decode(
{"error" => " An email address is required "}.to_json
)
This blog gives some more ideas.
精彩评论