RSpec自定义重定向匹配器始终成功

时间:2013-04-29 10:05:22

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

我已按照 Everyday Rails Testing with RSpec 一书中的示例创建了一个自定义RSpec匹配器,用于重定向到登录页面( requires_login 匹配器)。该匹配器的代码如下所示:

RSpec::Matchers.define :require_login do

  match do |actual|
    redirect_to Rails.application.routes.url_helpers.login_path
  end

  failure_message_for_should do |actual|
    "expected to require login to access the method"
  end

  failure_message_for_should_not do |actual|
    "expected not to require login to access method"
  end

  description do
    "redirect to the login form"
  end

end

然后在下面的示例中调用此匹配器:

describe "GET #edit" do

  it "requires login" do
    user = FactoryGirl.create(:user)
    get :edit, id: user
    expect(response).to require_login
  end

end # End GET #edit

出于某种原因,上述测试在以下情况下无效(即使它也检查重定向到登录路径):

describe "GET #edit" do

  it "requires login" do
    user = FactoryGirl.create(:user)
    get :edit, id: user
    expect(response).to redirect_to login_path
  end

end # End GET #edit

我已多次查看我的代码以及上面提到的书中的示例,但找不到任何错误。任何有关如何正确实现此匹配器的见解将不胜感激。我也使用Ruby 2.0.0,Rails 3.2.13和RSpec-Rails 2.13.1。

解决方案(感谢Frederick Cheung的建议)

RSpec::Matchers.define :require_login do |attribute|

  match do |actual|
    expect(attribute).to redirect_to Rails.application.routes.url_helpers.login_path
  end

  failure_message_for_should do |actual|
    "expected to require login to access the method"
  end

  failure_message_for_should_not do |actual|
    "expected not to require login to access method"
  end

  description do
    "redirect to the login form"
  end

end

1 个答案:

答案 0 :(得分:1)

你的匹配块需要返回匹配匹配的匹配,但是当你返回的东西总是真的。

您可能希望对redirect_to匹配器采用类似的方法,该匹配器调用提供的assert_redirected_to的rails并根据是否引发ActiveSupport::TestCase::Assertion返回true / false