2011-03-08 4 views
8

rspec, factory_girl & capybara로 통합 테스트를 작성하려고합니다. 나는 또한 오이를 설치했지만, 나는 그것을 (내 지식에) 사용하지 않고있다.Rspec & Capybara를 사용한 레일 3의 세션 테스트

기본적으로 내 사용자에게 db를 미리 채우고 싶습니다. 그런 다음 내 홈 페이지로 이동하여 로그인을 시도하십시오. user_path (@user)로 리디렉션해야합니다.

그러나 세션은 my/rspec/requests/integration 테스트에서 지속되지 않는 것처럼 보입니다.

내 사양 : /rspec/requests/users_spec.rb

require 'spec_helper' 

describe "User flow" do 

    before(:each) do 
    @user = Factory(:user) 
    end 

    it "should login user" do 

    visit("/index") 

    fill_in :email, :with => @user.email 
    fill_in :password, :with => @user.password 
    click_button "Login" 
    assert current_path == user_path(@user) 
    end 
end 

반환 대신

Failures: 

    1) User flow should login user 
    Failure/Error: assert current_path == user_path(@user) 
    <false> is not true. 
    # (eval):2:in `send' 
    # (eval):2:in `assert' 
    # ./spec/requests/users_spec.rb:16 

, 내 please_login_path로 리디렉션 - 로그인이 어떤 이유로 실패 할 경우 (발생해야하는 또는 [: user_id] 세션이 설정되지 않은 경우).

session.inspect를 넣으 려하면 nil 객체로 실패합니다. 내가 컨트롤러 테스트 (/rspec/controllers/sessions_spec.rb)에서이 작업을 수행하려고하면

, 나는 문제없이 세션에 액세스 할 수 있습니다, 나는 세션 호출 할 수 있습니다 [이 : USER_ID] 당신이 경우

+1

관련이 있는지는 잘 모르겠지만 @ user.password를 입력하여 사용자의 암호를 가져 오면 안됩니다. 이는 앱의 보안 취약점입니다. 암호를 일반 텍스트로 저장 하시겠습니까? –

+5

그것은 관련이 없으며 아마도 보안 취약점이 아닙니다. #password를 호출하면 Factory 변수로 인스턴스 변수에 설정되기 때문에 암호 만 반환됩니다. 아마도 그는 Devise 나 그와 비슷한 암호 특성을 db에 일반 텍스트로 저장하지 않을 가능성이 높기 때문에 그 인스턴스 변수를 사용할 수 없게 될 것입니다. –

답변

6

Devise를 사용한다면, in the warden wiki에 명시된대로 Warden :: Test :: Helpers (spec_helper의 요구가있는 바로 직후)를 포함시켜야합니다.

capybara가 통합 테스트로 실행 중일 때 액세스 할 수 없기 때문에 세션 호출은 nil을 반환합니다.

1

당신은 아마 이것에서 계속 전진했을 것입니다.하지만 저는 같은 질문으로 어려움을 겪고있었습니다. 문법의 문제였습니다. :email:password에 대한 기호를 사용하고 대신 문자열 ("email""password")을 사용해야합니다. 즉

, 노력이 변경이에

fill_in :email, :with => @user.email 
fill_in :password, :with => @user.password 

:

fill_in "email", :with => @user.email 
fill_in "password", :with => @user.password 
3

나도 같은 문제가 발생하고 양식을 작성하는 것은 일부 옵션이 될 수도 있지만, 나는에 있었다 제 3 자 인증 시스템 (Janrain이 정확해야 함)을 사용했기 때문에 제 인증 루비를 굴려보세요. 내 테스트에서 다음과 같은 것을 사용했습니다.

내 스펙/지원에있는 내용은 다음과 같습니다. 카피 바라와 셀레늄 내 요구 사양에 그런

module AuthTestHelper 

    class SessionBackdoorController < ::ApplicationController 
    def create 
     sign_in User.find(params[:user_id]) 
     head :ok 
    end 
    end 

    begin 
    _routes = Rails.application.routes 
    _routes.disable_clear_and_finalize = true 
    _routes.clear! 
    Rails.application.routes_reloader.paths.each{ |path| load(path) } 
    _routes.draw do 
     # here you can add any route you want 
     match "/test_login_backdoor", to: "session_backdoor#create" 
    end 
    ActiveSupport.on_load(:action_controller) { _routes.finalize! } 
    ensure 
    _routes.disable_clear_and_finalize = false 
    end 

    def request_signin_as(user) 
    visit "/test_login_backdoor?user_id=#{user.id}" 
    end 

    def signin_as(user) 
    session[:session_user] = user.id 
    end 

end 

/test_helpers_and_stuff.rb

이, 나는 다음과 같은 한 : BTW

describe "Giveaway Promotion" do 
    context "Story: A fan participates in a giveaway", js: :selenium do 
    context "as a signed in user" do 

     before :each do 
     @user = Factory(:user) 
     request_signin_as @user 
     end 

     it "should be able to participate as an already signed in user" do 
     visit giveaway_path 
     .... 
     end 
    end 
    end 
end 

을, 나는 this postthis post에 제안 된 솔루션을 시도한 후 솔루션을 함께했다 둘 다 나를 위해 일하지 않았다. (하지만 그들은 분명 내 솔루션에 영감을주었습니다)

행운을 빈다!

관련 문제