Search code examples
ruby-on-railsrubymongodbrspecrspec-rails

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.


Solution

  • 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.