2010-09-22 63 views
58

這裏我的HTTP應用程序控制器文件的基本身份驗證(application_controller.rb)軌道/ Rspec的製作測試通過使用HTTP基本身份驗證

before_filter :authenticate 

protected 

def authenticate 
    authenticate_or_request_with_http_basic do |username, password| 
    username == "username" && password == "password" 
    end 
end 

和我的家庭控制器的索引動作(規格默認的測試/ 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 

由於驗證方法,測試不會運行。我可以評論「before_filter:authenticate」來運行它們,但我想知道是否有辦法讓它們適用於該方法。

謝謝!

回答

121

更新:馬特·康諾利提供了一個GIST這也適用於請求和控制器的規格:http://gist.github.com/4158961


這樣做的另一種方式,如果你有很多的測試運行,不希望每次包括它(機代碼):

創建/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 

在您的測試規範文件:

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 

信用here

+0

很好的例子,謝謝。 – 2011-12-05 08:42:04

+1

它顯示請求是零爲我。任何想法如何得到解決方法? – chourobin 2012-04-05 20:01:54

+6

對於請求規範,你可以有多個請求,所以'request'是'nil'。相反,您需要創建一個env散列'env = {}',並將其更新到您的http_login方法中,然後像'get'/',{},env'中那樣顯式傳遞env。 – 2012-10-24 04:21:46

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 
4

當使用Rspec的測試葡萄API,以下語法工作

 post :create, {:entry => valid_attributes}, valid_session 

其中valid_session是

{'HTTP_AUTHORIZATION' => credentials} 

credentials = ActionController::HttpAuthentication::Token.encode_credentials("test_access1") 
1

這些是控制器和請求規格大的解決方案。

對於使用水豚功能測試,這裏是讓HTTP基本身份驗證工作的解決方案:

規格/支持/ when_authenticated。RB

RSpec.shared_context 'When authenticated' do 
    background do 
    authenticate 
    end 

    def authenticate 
    if page.driver.browser.respond_to?(:authorize) 
     # When headless 
     page.driver.browser.authorize(username, password) 
    else 
     # When javascript test 
     visit "http://#{username}:#{password}@#{host}:#{port}/"  
    end 
    end 

    def username 
    # Your value here. Replace with string or config location 
    Rails.application.secrets.http_auth_username 
    end 

    def password 
    # Your value here. Replace with string or config location 
    Rails.application.secrets.http_auth_password 
    end 

    def host 
    Capybara.current_session.server.host 
    end 

    def port 
    Capybara.current_session.server.port 
    end 
end 

然後,在你的規格:

feature 'User does something' do 
    include_context 'When authenticated' 

    # test examples 
end 
+0

非常有幫助! :) – 2017-05-16 20:49:37

4

一些答案建議設置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