我在阅读Ruby On Rails教程时遇到了这些问题 here
User类的验证是:
class User < ActiveRecord::Base
before_save { self.email = email.downcase }
validates :name, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, length: { maximum: 255 }
format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
.
.
.
end
在测试中,将更新的用户信息修补到用户的路线,如下所示:
def setup
@user = users(:michael)
end
.
.
.
test "successful edit" do
get edit_user_path(@user)
assert_template 'users/edit'
name = "Foo Bar"
email = "foo@bar.com"
patch user_path(@user), user: { name: name,
email: email,
password: "",
password_confirmation: "" }
assert_not flash.empty?
assert_redirected_to @user
@user.reload
assert_equal name, @user.name
email, @user.email
end
测试将通过,只会更新用户的姓名和电子邮件,密码不会更改。
如果密码验证不包含“allow_blank:true”,则此测试将失败。
所以我不明白:当测试通过时意味着密码可能为空,为什么它不会将密码更改为空白? Rails怎么知道我只想更新一些属性?
答案 0 :(得分:2)
has_secure_password
为您的模型添加password=
setter method方法,在设置密码时会丢弃empty?
输入。
irb(main):012:0> "".empty?
=> true
这可以防止用户选择空白密码。如果你不想接受我的话,你可以很容易地测试一下:
test "does not change password to empty string" do
patch user_path(@user), user: { name: name,
email: email,
password: "",
password_confirmation: "" }
@user.reload
assert_false @user.authenticate("")
end
但是,验证确实做的是,如果用户设置密码,则必须超过6个字符:
test "does not allow a password less than 6 characters" do
patch user_path(@user), user: { name: name,
email: email,
password: "abc",
password_confirmation: "abc" }
assert assigns(:user).errors.key?(:password)
end
(PS。这是在模型测试中比在控制器测试中更好的测试)