0

我想测试 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”凭据通过浏览器登录没问题,我可以看到我的应用程序的根页面。

如果有任何建议,我将不胜感激。

4

2 回答 2

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
于 2012-08-29T14:41:33.580 回答
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 的回答一样,您需要在访问任何页面之前执行此步骤。

我希望这可以节省其他人一些时间,我花了很长时间。

于 2020-06-23T14:22:06.423 回答