2016-08-24 6 views
8

私は、SessionsControllerにPOSTリクエストをして誰かが自分のサイトにログインできることをテストしようとしています。私はいくつかの場所でこの方法をお勧めしました:ユーザーがDeviseでサインインしているかどうかをテストします。

it 'must be able to sign in a user' do 
    user = create(:user) 
    post :create, format: :js, user: {email: user.email, password: user.password, remember_me: 0} 
    assert_response :success 
    @controller.current_user.must_equal user 
end 

しかし、このテストは正しくありません。 @controller.current_userを呼び出すと、投稿されたパラメータを使用してユーザーを認証しようとし、指定された電子メール/パスワードが正しい場合はuserを返します。 createアクションが実際にsign_inまたはcurrent_userを呼び出すという保証はありません。

これらのメソッドが呼び出されていることを確認するためにテストを書き直しても、他のメソッドを呼び出すことができます。 sign_out

最終的にユーザーがログインしているかどうかを確認する方法がありますか?そうであれば、そのユーザーは誰ですか。

EDIT -

SessionsController#はアクションを作成する場合、例えば、次のテストが

it 'must sign in a user' do 
    @controller.current_user.must_equal nil 
    post :create, format: :js, user: {email: @user.email, password: @user.password, remember_me: 0} 
    assert_response :success 
    @controller.current_user.must_equal @user 
end 

を通過するのである。で提案されているコードに最小限の変更を有する

def create 
    respond_to do |format| 
     format.js { 
     render nothing: true, status: 200 
     } 
    end 
end 
+0

助けてもらえますか? http://stackoverflow.com/questions/23793597/how-to-access-devise-current-user-in-a-rspec-feature-test – tmn4jq

+0

私はそれが助けてくれるとは思わないのでしょうか? current_userを呼び出すのに問題はありません。 – user1063998

+0

は '.current_user'でユーザをログインしようとするメソッドか、インスタンス変数のattr_readerですか?前者なら、あなたが描いているように見えるのは、期待される行動です。 –

答えて

2

ソリューション質問:

テストを開始する前に、システムを初期化する必要があります。あなたの私t 'must be able to sign in a user' doコードの前に次のコードを付加してみてください。

before (:each) do 
    user = FactoryGirl.create(:user) 
    sign_out user 
end 

これはあなたのポストコントローラ用の有効なテストにテストを有効にしてください。

説明:

私の仮定があり、上記のテストはいつも成功することを、ユーザーが既に署名されているので、(この1の前に実行される他の試験による)。 itの後の行にbyebugを使用して確認し、bybug'sコンソールでcurrent_userを実行してください。 nilでない場合、ユーザーは既にサインインしています。これはテストを無効にしています。

メモ(上記のコメントとは異なります)、current_userはユーザーのステータスを変更しません。読み取り専用機能です。

短い/クリーナー液:should change from nil to user Withステートメント

def sign_in_via_post(user) 
    post :create, format: :js, user: {email: user.email, password: user.password, remember_me: 0} 
end 

... 

before (:each) do 
    user = FactoryGirl.create(:user) 
    sign_out user 
end 

it 'must be able to sign in a user' do 
    { sign_in_via_post user }.should change { current_user }.from(nil).to(user) 
end 

は、あなたが確認し、ユーザーがその:私の意見では

は、以下のようなテストを実行するためのAAクリーンな方法がありますテストが開始される前にログアウトされ、テストが実行された後にユーザーがログインしています。

注、一部こと

{ sign_in_via_post user }.should change { current_user }.from(nil).to(user) 

は(多分より容易に理解する)コード論じhereとして

{ sign_in_via_post user }.should change { user_signed_in? }.from(false).to(true) 

と等価です。

+0

お返事ありがとうございます。私は 'current_user'がユーザーの状態を更新できると信じています。元の質問にサンプルテストを追加しましたが、私はこの問題を説明すると信じています。 – user1063998

+0

私はちょうど考えを持っていました。おそらく、何かをやっているbefore_action/filterがありますが、私は今チェックできません。おそらくあなたは正しいです – user1063998

+0

@ user1063998:あなたは私の提案をテストする機会を得ましたか?私は解決策を考えるのにかなりの時間を費やしてきた(少なくとも私はそれが解決策だと思う)。いずれにしても、それは良い練習でしたが、尋ねた人がチェックしてもらいたいと思っています。 – Olli

関連する問題