Как создать тест rspec, который проверяет ответ JSON?

У меня есть контроллер групп с методом def inbox.

Если пользователь является членом группы, то inbox возвращает объект JSON.

Если пользователь не является членом, то почтовый ящик должен перенаправляться благодаря разрешениям CanCan.

Как написать rspec для проверки этих двух вариантов использования?

Текущая спецификация:

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, :group => @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

Маршруты

inbox_group GET /groups/:id/inbox(.:format) {:controller=>"groups", :action=>"inbox"}

Файл маршрутов:

resources :groups do
  member do
    get 'vcard', 'inbox'
  end
  ....
end

Ответы

Ответ 1

Вот как я это делаю:

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

Я не использую cancan, поэтому я не могу помочь с этой частью.

Ответ 2

Попробуйте следующее:

_expected = {:order => order.details}.to_json
response.body.should == _expected

Ответ 3

Иногда может быть достаточно, чтобы убедиться, что response содержит действительный JSON, вот пример:

it 'responds with JSON' do
  expect {
    JSON.parse(response.body)
  }.to_not raise_error
end

Ответ 4

Я думаю, первое, что вы хотите сделать, это проверить, что ответ имеет правильный тип, т.е. он имеет заголовок Content-Type, установленный в application/json, что-то вроде строк:

it 'returns JSON' do
  expect(response.content_type).to eq(Mime::JSON)
end

Затем, в зависимости от вашего случая, вы можете проверить, можно ли проанализировать ответ как JSON, например wik:

it 'responds with JSON' do
  expect {
    JSON.parse(response.body)
  }.to_not raise_error
end

И вы можете объединить два вышеупомянутых теста в один тест, если вам кажется, что два теста для проверки достоверности ответа JSON слишком много.

Ответ 5

Чтобы утвердить JSON, вы также можете сделать это:

ActiveSupport::JSON.decode(response.body).should == ActiveSupport::JSON.decode(
  {"error" => " An email address is required "}.to_json
)

Этот блог дает несколько идей.