Closed yutokyokutyo closed 7 years ago
リスト 12.18に1行追加し、1つ前の演習課題に対するテストを書いてみましょう。ヒント: リスト 9.25のassert_nilメソッドとリスト 11.33のuser.reloadメソッドを組み合わせて、reset_digest属性を直接テストしてみましょう。
% git diff (git)-[Exercises-12.3.3]
diff --git a/test/integration/password_resets_test.rb b/test/integration/password_resets_test.rb
index 5c12946..39212e3 100644
--- a/test/integration/password_resets_test.rb
+++ b/test/integration/password_resets_test.rb
@@ -58,6 +58,7 @@ class PasswordResetsTest < ActionDispatch::IntegrationTest
assert is_logged_in?
assert_not flash.empty?
assert_redirected_to user
+ assert_nil @user.reset_digest
end
test "expired token" do
% rails t (git)-[Exercises-12.3.3]
Running via Spring preloader in process 36867
Started with run options --seed 10366
FAIL["test_password_resets", PasswordResetsTest, 2.9190750130001106]
test_password_resets#PasswordResetsTest (2.92s)
Expected "$2a$04$G.jarVpDd/Bcn7q5RfiKgemNR9Qe3jXx2yIXGvsDLfKkED0tw1PXK" to be nil.
test/integration/password_resets_test.rb:61:in `block in <class:PasswordResetsTest>'
47/47: [======================================================================================================================================] 100% Time: 00:00:03, Time: 00:00:03
Finished in 3.92936s
47 tests, 222 assertions, 1 failures, 0 errors, 0 skips
テストに失敗してしまった。
password resets のintegrationテストの中で有効なパスワードを入力した後にreset_digestがnilになることを確かめるテストを書いた。でも実際にはnilにならずに値が入っていた。なんでだろう?
binding.pryしてみると、やっぱり@user.reset_digest には 値が入っていた。
% rails t (git)-[Exercises-12.3.3]
Running via Spring preloader in process 38763
Started with run options --seed 16909
47/13: [==================================== ] 27% Time: 00:00:01, ETA: 00:00:05
Frame number: 0/29
From: /Users/y.kondo/project/workspace/rebuild_sample_app/test/integration/password_resets_test.rb @ line 62 PasswordResetsTest#test_password_resets:
57: password_confirmation: "foobaz" } }
58: assert is_logged_in?
59: assert_not flash.empty?
60: assert_redirected_to user
61: binding.pry
=> 62: assert_nil @user.reset_digest
63: end
64:
65: test "expired token" do
66: get new_password_reset_path
67: post password_resets_path,
[1] pry(#<PasswordResetsTest>)> @user.reset_digest
=> "$2a$04$YEQ1vsu8EXX858juB6v2JOYLaA8j8AZwjZuWZdMKqXoZ7iotIxENS"
app/controllers/password_resets_controller.rb の update アクションに書いた @user.update_attribute(:reset_digest, nil)
が実行されていればnilになるはず。その直前にpryを置いて本当に実行されているのかどうかを確かめてみよう。
% rails t test/integration/password_resets_test.rb (git)-[Exercises-12.3.3]
Running via Spring preloader in process 40515
Started with run options --seed 2586
2/1: [==================================================================== ] 50% Time: 00:00:01, ETA: 00:00:02
Frame number: 0/94
From: /Users/y.kondo/project/workspace/rebuild_sample_app/app/controllers/password_resets_controller.rb @ line 33 PasswordResetsController#update:
25: def update
26: if params[:user][:password].empty? # 新しいパスワードが空文字列になっていないか
27: @user.errors.add(:password, "can't be empty")
28: render 'edit'
29: elsif @user.update_attributes(user_params) # 新しいパスワードが正しければ、更新する
30: log_in @user
31: @user.update_attribute(:reset_digest, nil)
32: binding.pry
=> 33: flash[:success] = "Password has been reset."
34: redirect_to @user
35: else
36: render 'edit' # 無効なパスワードであれば失敗させる
37: end
38: end
[1] pry(#<PasswordResetsController>)> @user
=> #<User:0x007fd5438fa3e8
id: 762146111,
name: "Michael Example",
email: "michael@example.com",
created_at: Tue, 02 May 2017 00:46:15 UTC +00:00,
updated_at: Tue, 02 May 2017 00:46:16 UTC +00:00,
password_digest: "$2a$04$O8RgYo0yUkFZn9qXhBiRsO6fnObwsEM825PFc0uXBzShYZdpZ37vW",
remember_digest: nil,
admin: true,
activation_digest: nil,
activated: true,
activated_at: Tue, 02 May 2017 00:46:15 UTC +00:00,
reset_digest: nil,
reset_sent_at: Tue, 02 May 2017 00:46:16 UTC +00:00>
nil になってるじゃまいか!
大分絞れてきたので後はどのタイミングで呼ばれているか。テストの方で少しづつコメントアウトしてみて範囲を狭めていこう。
password_reset PATCH /password_resets/:id(.:format) password_resets#update
PUT /password_resets/:id(.:format) password_resets#update
このときだよなぁ
実装は合っているけどテストの書き方がミスっていた。 reload が必要なのであった。以前やった同じよう書き方を探すことにより解決。
テストが通ったのでマージ 💪