24

In Rails 3.2.9 I have custom error pages defines like this:

# application.rb
config.exceptions_app = self.routes

# routes.rb
match '/404' => 'errors#not_found'

Which works like expected. When I set config.consider_all_requests_local = false in development.rb I get the not_found view when visiting /foo

But how do I test this with Rspec + Capybara?

I've tried this:

# /spec/features/not_found_spec.rb
require 'spec_helper'
describe 'not found page' do
  it 'should respond with 404 page' do
    visit '/foo'
    page.should have_content('not found')
  end
end

When I run this spec I get:

1) not found page should respond with 404 page
  Failure/Error: visit '/foo'
  ActionController::RoutingError:
    No route matches [GET] "/foo"

How can I test this?

Edit:

Forgot to mention: I've set config.consider_all_requests_local = false in test.rb

Lasse Skindstad Ebert
  • 3,370
  • 2
  • 29
  • 28

6 Answers6

32

The problematic setting in the test.rb is not only the

consider_all_requests_local = false

but also

config.action_dispatch.show_exceptions = true

If you set this you should be able to test the error. I was not able to use it in an around filter.

Have a look for http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-and-testing-with-capybara/

Lars Schirrmeister
  • 2,215
  • 1
  • 22
  • 23
  • Thanks, that was exactly what I was missing. I thought the problem was deeper than that, so I had started digging around in Capybara... – Lasse Skindstad Ebert Jan 03 '13 at 18:29
  • What about for a controller spec? With these changes my feature specs work fine, but I'm still getting the failed test (with an ActiveRecord::RecordNotFound error) in a controller spec. Is there something I need to do differently for these? – robertwbradford Mar 21 '14 at 21:00
  • The link is broken and is now at http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-and-testing-with-capybara/ – Alex Villa Apr 22 '14 at 05:10
  • If you don't want to set this in the test.rb file you can check this solution http://stackoverflow.com/a/9941128/2989852 – Spyros May 05 '16 at 09:03
1

the config.consider_all_requests_local = false setting would need to be set in config/environments/test.rb in the same way you have done for your development one.

If you don't want to do this for all tests, perhaps an rspec around filter would be useful to set the state before the test and restore afterwards like so:

# /spec/features/not_found_spec.rb
require 'spec_helper'
describe 'not found page' do
  around :each do |example|
     Rails.application.config.consider_all_requests_local = false
     example.run
     Rails.application.config.consider_all_requests_local = true
  end

  it 'should respond with 404 page' do
    visit '/foo'
    page.should have_content('not found')
  end
end
loz
  • 117
  • 2
1

If you want to do it and don't want to change config/environments/test.rb, you can follow the solution from this post.

Community
  • 1
  • 1
William Weckl
  • 2,435
  • 4
  • 26
  • 43
0

You can access directly 404 error page:

Visit /404 instead of /foo

Cà phê đen
  • 1,883
  • 2
  • 21
  • 20
Đoàn Nghĩa
  • 116
  • 1
  • 1
0

The variables from Rails.application.config are read at the start of the test suite to a separate hash (Rails.application.env_config) - so changing the source variables for a particular spec doesn't work.

I was able to solve this with the following around block - this allows testing the exception rescue without impacting the rest of the test suite

 around do |example|
    orig_show_exceptions = Rails.application.env_config['action_dispatch.show_exceptions']
    orig_detailed_exceptions = Rails.application.env_config['action_dispatch.show_detailed_exceptions']

    Rails.application.env_config['action_dispatch.show_exceptions'] = true
    Rails.application.env_config['action_dispatch.show_detailed_exceptions'] = false

    example.run

    Rails.application.env_config['action_dispatch.show_detailed_exceptions'] = orig_detailed_exceptions
    Rails.application.env_config['action_dispatch.show_exceptions'] = orig_show_exceptions
  end
jebw
  • 1
-1

With Rails 5.2, Capybara 3 I was able to simulate page errors with the following

around do |example|
  Rails.application.config.action_dispatch.show_exceptions = true
  example.run
  Rails.application.config.action_dispatch.show_exceptions = false
end

before do
  allow(Person).to receive(:search).and_raise 'App error simulation!'
end

it 'displays an error message' do
  visit root_path
  fill_in 'q', with: 'anything'
  click_on 'Search'
  expect(page).to have_content 'We are sorry, but the application encountered a problem.'
end

Update

This seems to not always work when running the full test suite. So I had to set config.action_dispatch.show_exceptions = true in config/environments/test.rb and remove the around block.

HarlemSquirrel
  • 8,966
  • 5
  • 34
  • 34