使用Rspec + Capybara测试Rails中的错误页面

24

在Rails 3.2.9中,我有如下定义自定义错误页面的方式:

# application.rb
config.exceptions_app = self.routes

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

这个功能的表现符合预期。当我在development.rb中设置config.consider_all_requests_local = false时,访问/foo会显示not_found视图。

但是如何使用Rspec + Capybara测试呢?

我已经尝试过这样:

# /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

当我运行这个规范时,我得到:

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

我该如何测试这个?

编辑:

忘了说:我在test.rb中设置了config.consider_all_requests_local = false

6个回答

32

谢谢,这正是我所缺少的。我以为问题比那更深入,所以我已经开始在Capybara周围挖掘了... - Lasse Skindstad Ebert
那么控制器规范呢?通过这些更改,我的功能规范可以正常工作,但我在控制器规范中仍然会遇到失败的测试(带有ActiveRecord :: RecordNotFound错误)。我需要为此做出不同的处理吗? - robertwbradford
链接已经失效,现在可在http://agileleague.com/blog/rails-3-2-custom-error-pages-the-exceptions_app-and-testing-with-capybara/上找到。 - Alex Villa
如果你不想在test.rb文件中设置这个,你可以查看这个解决方案 https://dev59.com/_Wox5IYBdhLWcg3wvWoy#9941128 - Spyros

1

需要在config/environments/test.rb中设置config.consider_all_requests_local = false,就像你为开发环境所做的那样。

如果您不想为所有测试都这样做,也许一个rspec around filter会很有用,可以在测试之前设置状态并在之后恢复,如下所示:

# /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

我忘了提到,我已经尝试在 test.rb 中设置 consider_all_requests_local = false - Lasse Skindstad Ebert
3
好的,我会尽力进行翻译。你所提供的内容是:For me too, I have ActionController::RoutingError: - Artur79

1

如果你想这样做,又不想修改 config/environments/test.rb,你可以按照这个 post 的解决方案进行操作。


0

您可以直接访问404错误页面:

访问/404而不是/foo


0

Rails.application.config 中的变量在测试套件开始时读取到一个单独的哈希表 (Rails.application.env_config) 中 - 因此更改特定规范的源变量是不起作用的。

我能够通过以下环绕块解决这个问题 - 这允许测试异常救援而不影响测试套件的其余部分。

 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

-1

使用Rails 5.2和Capybara 3,我能够通过以下方式模拟页面错误

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

更新

当运行完整的测试套件时,似乎这并不总是有效。因此,我不得不在config/environments/test.rb中设置config.action_dispatch.show_exceptions = true并删除周围的块。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接