我想在Rails 3.2.3中测试内置的基本http认证机制。我试图在RSpec和Cucumber中测试http身份验证,但两个工具都有失败的步骤。在Cucumber中,我在运行我的功能时收到以下消息:
When I perform HTTP authentication as "admin" with "test" # features/step_definitions/web_steps.rb:1
undefined method `env' for nil:NilClass (NoMethodError)
./features/step_definitions/web_steps.rb:3:in `/^I perform HTTP authentication as "([^\"]*)" with "([^\"]*)"$/'
features/sign_in_http.feature:4:in `When I perform HTTP authentication as "admin" with "test"'
这是我的ApplicationController类:
class ApplicationController < ActionController::Base
protect_from_forgery
http_basic_authenticate_with :name => "admin", :password => "test"
end
Cucumber中的步骤定义:
When /^I perform HTTP authentication as "([^\"]*)" with "([^\"]*)"$/ do |username, password|
@request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("username:password")
visit '/'
end
黄瓜特征:
Feature: Signing in via http
Scenario: HTTP sign-in
When I perform HTTP authentication as "admin" with "test"
Then I should see "Welcome to the app."
在RSpec中,http身份验证步骤似乎已过,但我从后续步骤收到消息,因为“访问被拒绝”,因此无法在页面上找到预期的内容:
1) ApplicationController sign in via http should be successful
Failure/Error: page.should have_content("Welcome to the app.")
expected there to be content "Welcome to the app." in "HTTP Basic: Access denied.\n"
# ./spec/controllers/application_controller_spec.rb:12:in `block (3 levels) in <top (required)>'
这是我的相关规范:
require 'spec_helper'
describe ApplicationController do
describe "sign in via http" do
it "should be successful" do
@request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("admin:test")
visit '/'
response.should be_success
page.should have_content("Welcome to the app.")
end
end
end
我还尝试在黄瓜步骤中的http授权行之前访问根路径,但是这给了我关于 @request 的NilClass的相同消息。
使用定义的“admin:test”凭据通过浏览器登录是没有问题的,我可以看到我的应用程序的根页面。
我会感谢任何建议。
答案 0 :(得分:3)
以下是我如何使用它。关键是在访问任何页面之前运行身份验证步骤,否则您的身份验证失败了。
在我的专题中,我说:
Background:
Given I perform HTTP authentication as "<id>/<password>"
When I go to the homepage
Then I should see "Text-that-you-should-see-on-your-home-page"
HTTP身份验证的步骤定义如下(我在其他地方找到了此代码并添加了puts语句以查看发生了什么)。
Given /^I perform HTTP authentication as "([^\"]*)\/([^\"]*)"$/ do |username, password|
puts "id/pswd: #{username}/#{password}"
### Following works ONLY if performed first before even going to a page!!!
if page.driver.respond_to?(:basic_auth)
puts 'Responds to basic_auth'
page.driver.basic_auth(username, password)
elsif page.driver.respond_to?(:basic_authorize)
puts 'Responds to basic_authorize'
page.driver.basic_authorize(username, password)
elsif page.driver.respond_to?(:browser) && page.driver.browser.respond_to?(:basic_authorize)
puts 'Responds to browser_basic_authorize'
page.driver.browser.basic_authorize(username, password)
else
raise "I don't know how to log in!"
end
end
答案 1 :(得分:0)
现在有一个简单得多的解决方案。我不知道它何时实现,但是Cucumber现在有一个方法basic_authorize
来解决这个问题。这是我使用的步骤:
Given /^I perform basic HTTP authentication with username "([^"]*)" and password "([^"]*)"$/ do |username, password|
basic_authorize(username, password)
end
这是一个示例用例:
Given I perform basic HTTP authentication with username "cool_user" and password "hunter22"
与JESii的答案一样,您需要在访问任何页面之前执行此步骤。
我希望这可以节省其他人的时间,我为此花了很长时间。