24
votes

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

5

5 Answers

30
votes

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/

1
votes

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
1
votes

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

0
votes

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.

0
votes

You can access directly 404 error page:

Visit /404 instead of /foo