Alex Castaño
Alex Castaño

Reputation: 41

How to test that a request does not return 500 error?

I am trying to create an RSpec test which detects if a request can crash the controller, usually a 500 error. So I want to be able to distinguish between:

 nil.invalid_method # raises NoMethodError

from

 params.require(:required_parameter) # raises ActionController::ParameterMissing

in a controller in a generic way. When I do a request,feature or controller test it raises an exception:

describe "Post", type: :request do
  it 'does not crash when no params given' do
    post '/posts' # this line launches an exception
    expect(page).to_not have_http_status(500)
  end
end

It seems that before RSpec (or Rails I don't know) had a different behaviour, similar to I'm looking for:

How can I do this? Or how would you do?

Thanks for your time.

Upvotes: 1

Views: 3730

Answers (2)

max
max

Reputation: 102045

You can test that the controller does not raise an uncaught exception by using the raise_error matcher:

RSpec.describe "Things", type: :request do
  describe "POST /things" do
    it "does not raise an error" do
      # we pass a block to expect
      expect { post things_path }.to_not raise_error
    end
  end
end

If the exception is rescued in the controller by using the rescue keyword or Rails rescue_from you would test the response code as usual:

class ThingsController < ApplicationController
  rescue_from ActionController::ParameterMissing do
    head 500
  end

  def create
    raise ActionController::ParameterMissing.new('foo')
  end
end

RSpec.describe "Things", type: :request do
  describe "POST /things" do
    it "work even if the param is not provided" do
      post things_path
      expect(response).to successful
    end
  end
end

In this case it is much more useful to test that the response is what you expected it to be - not that it is not a 500.

Upvotes: 0

spickermann
spickermann

Reputation: 106892

You can use a controller spec that doesn't render a 500, but raises the exception instead:

describe "PostController", type: :controller do
  describe "POST index" do
    it 'does not crash with valid params' do
      expect {
        post :index, { post: { title: 'foo' } }
      }.to_not raise_exception 
    end
  end

  describe "POST index" do
    it 'crashes without params' do
      expect {
        post :index
      }.to raise_exception(ActionController::ParameterMissing)
    end
  end
end

Also note the curly brackets { ... } after expect.

Upvotes: 1

Related Questions