2

bcrypt-rubyと を使用してユーザー認証を行う基本的なアプリケーションをまとめましたhas_secure_password結果は、基本的にRails Tutorialのアプリケーションのベアボーン バージョンです。つまり、RESTful ユーザー モデルと、サインインおよびサインアウト機能を備えています。

ユーザー情報を編集するためのテストの一環として、パスワードを変更するためのテストを作成しました。パスワードの変更はブラウザで問題なく機能しますが、以下のテストはパスしません。

subject { page }

describe "successful password change"
  let(:new_password) { "foobaz" }
  before do
    fill_in "Password",               with: new_password
    fill_in "Password Confirmation",  with: new_password
    click_button "Save changes"
  end

  specify { user.reload.password.should == new_password }
end

明らかに、ここでいくつかの基本的な詳細を誤解しています。

要するに:

1) 上記のコードが機能しないのはなぜですか? パスワードの変更機能はブラウザで機能します。その間、rspec上記の最後の行で古いパスワードを再読み込みし続けます。そして、テストは失敗します。

2) パスワードの変更をテストするより良い方法は何ですか?

編集:

初期パスワードを に設定するfoobarと、エラー メッセージは次のようになります。

Failure/Error: specify { user.reload.password.should == new_password }
   expected: "foobaz"
        got: "foobar" (using ==)

基本的に、beforeブロックは実際には新しいパスワードを保存していないようです。

参考までに、関連するコントローラー アクションは次のとおりです。

def update
  @user = User.find(params[:id])
  if @user.update_attributes(params[:user])
    flash[:success] = "Profile Updated"
    sign_in @user
    redirect_to root_path
  else
    render 'edit'
  end
end
4

3 に答える 3

7

Devise ユーザーの場合は、#valid_password?代わりに次を使用します。

expect(user.valid_password?('correct_password')).to be(true)

クレジット: Ryan Bigg

于 2016-08-28T04:29:06.617 に答える
2

あなたの答え(を使用authenticate)は正しいアプローチです。あなたはそれに満足するはずです。モデル内の @password (attr_accessor 経由) ではなく、パスワードのハッシュ化されたバージョンを比較したい。実際のパスワードではなく、ハッシュを保存していることに注意してください。

あなたuserのテストは、メモリ内のそのユーザーのコピーです。テストを実行すると、更新メソッドはそのユーザーの別のコピーをメモリにロードし、データベースに保存されているパスワード ハッシュを更新します。コピーは変更されません。これが、データベースから更新されたデータを取得するためにリロードすることを考えた理由です。

パスワードフィールドはデータベースに保存されず、代わりにハッシュとして保存されるため、新しいハッシュがデータベースからリロードされますが、encrypted_pa​​ssword のuser代わりにインスタンスの @password の一時的な状態を比較していました。

于 2013-08-04T04:13:31.560 に答える
2

ここであまり満足のいく解決策ではないのは、#authenticateによって提供されるメソッドを使用してテストを作成することbcrypt-rubyです。

specify { user.reload.authenticate(new_password).should be_true }

確かに、これは適切な統合テストではありませんが、グリーンになるでしょう。

于 2013-08-04T02:45:13.683 に答える