我已按照 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
答案 0 :(得分:1)
你的匹配块需要返回匹配匹配的匹配,但是当你返回的东西总是真的。
您可能希望对redirect_to匹配器采用类似的方法,该匹配器调用提供的assert_redirected_to
的rails并根据是否引发ActiveSupport::TestCase::Assertion
返回true / false