Reputation: 12663
I have a rails controller that returns only 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
What is the correct way to test that the action is returning the expected @json objects?
I've tried the following
describe "GET #index" do
before :each do
get :index, filtered: 'someValue'
end
it { expect( response.body ).to eq 'my expected response' }
end
But I'm getting
Failure/Error: it { expect( response.body ).to eq 'my expected response' }
expected: 'my expected response'
got: "[]"
I'm having trouble determining whether there is a problem in the underlying controller, or whether I've simply written a bad test.
Is response.body
the correct way to get the json payload?
Help appreciated!
Upvotes: 2
Views: 4373
Reputation: 102423
Both your controller and spec are somewhat off.
You don't need to call
to_json
on the object that you want to render. If you use the:json
option, render will automatically callto_json
for you.
http://guides.rubyonrails.org/layouts_and_rendering.html
The reason your spec is giving you "[]"
is that Model.where(some_conditions)
is returning an empty collection. An empty collection renders as an empty array in JSON.
Either the scope does not work as intended or your test setup is flawed. Remember that let variables are lazy loading and you either need to use let!
or reference the variable for records to be inserted into the test 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
Upvotes: 4