Rails/Rspec使用http基本身份验证进行测试

ben*_*itr 66 rspec ruby-on-rails http-authentication

这里我的应用程序控制器文件中的http基本身份验证(application_controller.rb)

before_filter :authenticate

protected

def authenticate
  authenticate_or_request_with_http_basic do |username, password|
    username == "username" && password == "password"  
  end
end
Run Code Online (Sandbox Code Playgroud)

和我的家庭控制器的索引操作的默认测试(spec/controllers/home_controller_spec.rb)

require 'spec_helper'

describe HomeController do

describe "GET 'index'" do
  it "should be successful" do
    get 'index'
    response.should be_success
  end
end
Run Code Online (Sandbox Code Playgroud)

由于身份验证方法,测试无法运行.我可以评论"before_filter:authenticate"来运行它们,但我想知道是否有办法让它们使用该方法.

谢谢!

iwa*_*bed 134

更新(2013):Matt Connolly提供了一个GIST,它也适用于请求和控制器规范:http://gist.github.com/4158961


如果您要运行许多测试并且不希望每次都包含它,那么另一种方法(DRYer代码):

创建/spec/support/auth_helper.rb文件:

module AuthHelper
  def http_login
    user = 'username'
    pw = 'password'
    request.env['HTTP_AUTHORIZATION'] = ActionController::HttpAuthentication::Basic.encode_credentials(user,pw)
  end  
end
Run Code Online (Sandbox Code Playgroud)

在您的测试规范文件中:

describe HomeController do
  render_views

  # login to http basic auth
  include AuthHelper
  before(:each) do
    http_login
  end

  describe "GET 'index'" do
    it "should be successful" do
      get 'index'
      response.should be_success
    end
  end

end
Run Code Online (Sandbox Code Playgroud)

相信这里

  • 对于请求规范,您可以有多个请求,因此`request`是'nil`.相反,你需要创建一个env哈希`env = {}`,在你的http_login方法中更新它,然后在`get'/',{},env`中显式传入env. (6认同)
  • 扩展上述内容,适用于请求和控制器规范:https://gist.github.com/4158961 (6认同)

ben*_*itr 17

对不起,我没有找到足够的,解决方案似乎如下:

describe "GET 'index'" do
  it "should be successful" do
    @request.env["HTTP_AUTHORIZATION"] = "Basic " + Base64::encode64("username:password")
    get 'index'
    response.should be_success
  end
end
Run Code Online (Sandbox Code Playgroud)


Ken*_* S. 7

对于我来说,使用 Rails 6,我需要 rspec get 方法的关键字参数,例如 ..get route, params: params, headers: headers

验证助手方法

module AuthHelper
  def headers(options = {})
    user = ENV['BASIC_AUTH_USER']
    pw = ENV['BASIC_AUTH_PASSWORD']

    { HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,pw) }
  end
  def auth_get(route, params = {})
    get route, params: params, headers: headers
  end
end
Run Code Online (Sandbox Code Playgroud)

rspec 请求测试。

describe HomeController, type: :request do    
  include AuthHelper

  describe "GET 'index'" do
    it "should be successful" do
      auth_get 'index'
      expect(response).to be_successful
    end
  end

end
Run Code Online (Sandbox Code Playgroud)


Dan*_*hka 6

一些答案建议设置request.env哪个是不安全的,因为请求可能nil会结束private method env' called for nil:NilClass,尤其是在运行单个测试时rspec -e

正确的方法是:

def http_login
  user = 'user'
  password = 'passw'
  {
    HTTP_AUTHORIZATION: ActionController::HttpAuthentication::Basic.encode_credentials(user,password)
  }
end

get 'index', nil, http_login

post 'index', {data: 'post-data'}, http_login
Run Code Online (Sandbox Code Playgroud)