预期的ActionController :: RoutingError但在rails app rspec中没有给出一个块

时间:2017-02-27 11:01:45

标签: ruby-on-rails capybara rspec-rails

我尝试测试我的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

2 个答案:

答案 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驱动)而不是功能测试中真正更好测试的东西。

如果您坚持在功能测试中对此进行测试,那么您需要验证一些事项

  1. 确保您在测试环境中没有任何可以捕获错误并生成漂亮/详细错误页面的宝石。这将包括像web_consolebetter_errors等宝石。这些宝石应该只在开发环境中。

  2. 确保在测试配置中设置了Capybara.raise_server_errors = true

  3. 您可能需要在块内添加第二个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)