2016-12-01 6 views
1

У меня есть контроллер рельсы, который возвращает только JSONКак проверить ответ json в тестах контроллера?

def index 
    if params[:filtered] = 'someValue' 
    @json = Model.where(some_conditions).to_json 
    else 
    @json = Model.where(some_other_conditions).to_json 
    end 
    render json: @json 
end 

Что такое правильный способ проверить, что действие возвращает ожидаемый @json объектов?

Я попытался следующие

describe "GET #index" do 
    before :each do 
    get :index, filtered: 'someValue' 
    end 
    it { expect(response.body).to eq 'my expected response' } 
end 

Но я получаю

Failure/Error: it { expect(response.body).to eq 'my expected response' } 
expected: 'my expected response' 
got: "[]" 

У меня возникли проблемы определения того, существует проблема в базовом контроллере, или Я просто написал плохой тест.

Действительно ли response.body правильный способ получить полезную нагрузку json?

Помогите оценить!

+0

пустой массив будет возвращен, если запрос не возвращает результат. –

+0

Да, я это понимаю. Но верно ли обратное? Если 'response.body' содержит объекты json, если запрос возвращает объекты. На этом этапе я считаю, что запрос должен содержать объекты. –

+0

Thats true. Если ответ возвращает объекты, тогда ответ будет иметь их, конечно, сериализован для json. –

ответ

2

Оба контроллера и спецификации несколько выключены.

Вам не нужно вызывать to_json на объект, который вы хотите визуализировать. Если вы используете опцию :json, рендер автоматически вызовет to_json .
http://guides.rubyonrails.org/layouts_and_rendering.html

Причина вашей спецификации дает вам "[]", что Model.where(some_conditions) возвращается пустая коллекция. Пустая коллекция отображает пустой массив в JSON.

Либо область действия не работает должным образом, либо ваша тестовая установка испорчена. Помните, что пусть переменные являются ленивой загрузкой, и вам нужно либо использовать let!, либо ссылаться на переменную для записей, которые нужно вставить в тестовую db.

# polyfill for Rails 4. Remove if you are using Rails 5. 
let(:parsed_response) { response.body.to_json } 

describe "GET #index" do 
    # or use fixtures/factories 
    let!(:model) { Model.create!(foo: 'bar') } 
    before :each do 
    get :index, filtered: 'someValue' 
    end 
    expect(parsed_response.first["id"].to_i).to eq model.id 
end 
+0

Кроме того, спецификации контроллеров находятся на пути с появлением Rails 5 и обесцениванием многих методов, таких как 'assigns' и' assert_renders'. Используйте опцию [request specs вместо] (https://everydayrails.com/2016/08/29/replace-rspec-controller-tests.html) для будущих спецификаций. – max

Смежные вопросы