Pablo Palacios Pablo Palacios - 3 months ago 17
Ruby Question

How to test Mongo connection error handling with RSpec

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.

Answer

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.

Comments