Reputation: 474
I have a method to update people's attribute, and it will rescue ActiveRecord::RecordNotFound
if the people cannot be found. The method is:
def update
@people= People.find(params[:id])
if @people.update(people_params)
render json: { success: 'Success' }
else
render :edit
end
rescue ActiveRecord::RecordNotFound => e
render json: { error: 'Failed') }
end
And I want to test the situation when the record not found, here's my test for now:
let(:people) { create(:people) }
let(:people_id) { people.id }
let(:user) { people}
# Other tests...
context 'when person not found' do
let(:exception) { ActiveRecord::RecordNotFound }
# What should I write so that I can let the record not been found?
before { allow(People).to receive(:find).and_raise(exception) }
it 'responds with json containing the error message' do
expect(JSON.parse(response.body)).to eq({error:'Error'})
end
end
I want my test executed under the condition that records not found. But I don't know how to do it. I tried to set let(people) {nil}
but it not work. Is there an anyway to do that? Thanks!
Upvotes: 2
Views: 2238
Reputation: 101811
This is not a good solution to begin with. In Rails you want to use rescue_from
to handle common errors on the controller level.
class ApplicationController
rescue_from ActiveRecord::RecordNotFound, with: :not_found
def not_found
respond_to do |format|
format.json { head :404 }
end
end
end
This lets you use inheritance to DRY your code.
render json: { error: 'Failed') }
Is an anti-pattern. If the request failed you should tell the client by sending the correct HTTP status code.
If you want to test that your controller handles a missing resource correctly you would do:
let(:people) { create(:people) }
let(:people_id) { people.id }
let(:user) { people}
it "returns the correct response code if the person cannot be found" do
get '/people/notarealid'
expect(response).to have_http_status :not_found
end
This does not use any stubbing and actually tests the implementation.
Upvotes: 5
Reputation: 1
you can try :
let!(:error_failed) { { error: 'Failed' } }
context 'when people is not found by params' do
it 'return 404 and render json failed'
null_object = double.as_null_object
allow(People).to receive(:find).with(params[:id]).and_raise(ActiveRecord::RecordNotFound.new(null_object)
put :update, format: :json, .....
expect(response.body).to error_dailed.to_json
expect(response.status).to .....
end
end
Upvotes: -3