I need to solve a test of my app. Coverage is complaining about a line of code that evaluates the connection to MongoDB (rescue Mongo::Error::NoServerAvailable => _e
) and renders the error.
What do you think I should use to test this:
def index
render json: Complex.all.to_json
rescue Mongo::Error::NoServerAvailable => _e
render json: { error_description: 'no database available' }, status: 503
end
I am trying to test with something like:
it 'should return an exception' do
get :index
expect(response).to raise_exception
end
I found that I should use
.and_raise(IOError)
But I am not sure where to use it to make it fall on the line. Actually I can make it fall on the exception if I stop Mongo, but that's not the idea.
Thanks for your time.
To reach the line of code that handles the exception, stub Complex.all.to_json
to raise the exception. Since Complex.all.json
is chained it takes a little extra effort to stub it. Also, since the exception is handled, you can't test that it's raised; instead, test the result of handling it.
it 'should handle the exception' do
all = double
allow(all).to receive(:to_json).and_raise Mongo::Error::NoServerAvailable
allow(Complex).to receive(:all).and_return all
get :index
expect(response.status).to eq(503)
expect(response.body).to include('no database available')
# you could test the JSON more thoroughly, but you get the idea
end
You could use receive_message_chain
to stub Complex.all.to_json
with less code. I used the long version since it's easier to understand what's going on.