我尝试测试我的RoR应用程序。当我测试在我的控制器中导致ActionController :: RoutingError时,我得到以下错误: 得到1个失败和另外1个错误:
2.1) Failure/Error: expect(visit meters_path).to raise_error(ActionController::RoutingError)
expected ActionController::RoutingError but was not given a block
# ./spec/integration/meter_behavior_spec.rb:70:in `block (2 levels) in <top (required)>'
2.2) Failure/Error: raise ActionController::RoutingError.new('Not Found')
ActionController::RoutingError:
Not Found
是什么原因? 这是我的测试宝石列表:
group :development, :test do
gem 'factory_girl_rails'
gem 'faker'
gem 'rspec-rails'
end
group :test do
gem 'capybara'
gem 'database_cleaner'
gem 'launchy'
gem 'selenium-webdriver', '2.53.4'
gem 'capybara-webkit'
gem 'shoulda-matchers', '~> 3.1'
end
我的spec文件
meter_behavior_spec.rb
scenario 'a visitor cannot to view meters pages', driver: :webkit do
user = FactoryGirl.create(:client1)
user.meters.create(attributes_for(:meter))
expect(visit meters_path).to raise_error(ActionController::RoutingError)
end
meters_controller.rb:
before_action only: :index do
access_allowed_for(['Client'])
end
# GET /meters
# GET /meters.json
def index
respond_to do |format|
format.json { render json: MetersDatatable.new(view_context, current_user) }
format.html
end
end
application_controller.rb:
def access_allowed_for(statuses_ary=[])
statuses_ary << 'Admin'
if !user_signed_in? || statuses_ary.exclude?(current_user.try(:status))
raise ActionController::RoutingError.new('Not Found')
end
end
答案 0 :(得分:1)
我相信你应该简单地将访问米_路径作为一个块而不是作为参数传递,如下所示:
expect{visit meters_path}.to raise_error(ActionController::RoutingError)
见:
https://www.relishapp.com/rspec/rspec-expectations/v/2-2/docs/matchers/expect-error
告诉我它是否有效。
答案 1 :(得分:1)
Jean-Christophe的答案中指出的第一个问题是raise_error
匹配器需要一个块。第二个问题是你正在测试一些在控制器测试(不是Capybara驱动)而不是功能测试中真正更好测试的东西。
如果您坚持在功能测试中对此进行测试,那么您需要验证一些事项
确保您在测试环境中没有任何可以捕获错误并生成漂亮/详细错误页面的宝石。这将包括像web_console
,better_errors
等宝石。这些宝石应该只在开发环境中。
确保在测试配置中设置了Capybara.raise_server_errors = true
您可能需要在块内添加第二个Capybara语句。这是因为Capybara在与测试不同的线程中运行应用程序,并且访问调用可能异步发生(取决于您使用的驱动程序)。这意味着当访问调用返回时可能实际上没有引发错误。通过向capybara方法添加第二次调用,它将等待一段时间以完成访问,然后检测到服务器/应用程序线程中出现错误并在测试线程中重新引发该错误。
expect{
visit meters_path
page.has_text? 'Random text' # only here to give time for app to raise error
}.to raise_error(ActionController::RoutingError)