Railsチュートリアルの第6章、6.3.3 「パスワードの最小文字数」のところが理解しづらかったので、メモを残しておく。
なぜ下記の2つで、パスワードが6文字以上というのをテストできるのだろうか。
require 'test_helper'
class UserTest < ActiveSupport::TestCase
def setup
@user = User.new(name: "Example User", email: "user@example.com",
password: "foobar", password_confirmation: "foobar")
end
.
.
.
test "password should be present (nonblank)" do
@user.password = @user.password_confirmation = " " * 6
assert_not @user.valid?
end
test "password should have a minimum length" do
@user.password = @user.password_confirmation = "a" * 5
assert_not @user.valid?
end
end
モデルはこうなっている。
class User < ApplicationRecord
.
.
.
has_secure_password
validates :password, presence: true, length: { minimum: 6 }
end
モデルに書いてある最小文字数が、5文字以下だとテストに通らない理由、7文字以上だとテストに通らない理由、それぞれに分けて考える。
まず、モデルに書いてある最小文字数が5文字以下だった場合。
class User < ApplicationRecord
.
.
.
has_secure_password
validates :password, presence: true, length: { minimum: 5 }
end
テストは失敗する。
Running via Spring preloader in process 10030
Started with run options --seed 1981
FAIL["test_password_should_have_a_minimum_length", UserTest, 0.6743489999789745]
test_password_should_have_a_minimum_length#UserTest (0.67s)
Expected true to be nil or false
test/models/user_test.rb:75:in `block in <class:UserTest>'
17/17: [==================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.76646s
17 tests, 33 assertions, 1 failures, 0 errors, 0 skips
なぜか?
これは、user_test.rbにおいて、assertionがfalseとなるようなvalidationとしないといけないのに、
@user.password = @user.password_confirmation = "a" * 5
ここに書いてある5文字と一致してしまうからである。
もし、モデルにおいて、minimum=4 としても同じである。
テストが5文字なので、assertionはtrueとなる。(よってテストは失敗する)
ゆえに、パスワードの最低文字数は6文字以上でないとならない。
では、パスワードの最低文字数を7文字にするとどうなるのか?
class User < ApplicationRecord
.
.
.
has_secure_password
validates :password, presence: true, length: { minimum: 7 }
end
またしてもテストは失敗する。
Started with run options --seed 10515
ERROR["test_email_addresses_should_be_saved_as_lower-case", UserTest, 0.7198919999646023]
test_email_addresses_should_be_saved_as_lower-case#UserTest (0.72s)
ActiveRecord::RecordNotFound: ActiveRecord::RecordNotFound: Couldn't find User without an ID
test/models/user_test.rb:60:in `block in <class:UserTest>'
FAIL["test_should_be_valid", UserTest, 0.7460710000013933]
test_should_be_valid#UserTest (0.75s)
Expected false to be truthy.
test/models/user_test.rb:13:in `block in <class:UserTest>'
17/17: [==================================================] 100% Time: 00:00:00, Time: 00:00:00
Finished in 0.77979s
17 tests, 32 assertions, 1 failures, 1 errors, 0 skips
なぜ失敗するのだろうか?
エラーをよく見ると、"test_should_be_valid" のところで失敗している。
これはよく考えると、setupのところでpassword: "foobar" と指定しており、これが6文字なのである。「パスワードは7文字以上」というバリデーションにすると、そもそもこの"foobar"は登録できない。なのでテストが失敗する。
よって、パスワードは6文字以下でなければならないのである。
(よくできているなぁ・・・)