[英]Rspec tests for checking uniqueness
Here is the rspec test to check the uniqueness of an email ( from http://ruby.railstutorial.org/chapters/modeling-users.html#code-validates_uniqueness_of_email_test ) 以下是检查电子邮件唯一性的rspec测试(来自http://ruby.railstutorial.org/chapters/modeling-users.html#code-validates_uniqueness_of_email_test )
require 'spec_helper'
describe User do
before do
@user = User.new(name: "Example User", email: "user@example.com")
end
.
.
.
describe "when email address is already taken" do
before do
user_with_same_email = @user.dup
user_with_same_email.save
end
it { should_not be_valid }
end
end
As the author mentioned, I added 正如作者所说,我补充道
class User < ActiveRecord::Base
.
.
.
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: true
end
to my user model and the tests pass. 到我的用户模型和测试通过。
But @user hasn't yet been saved to the database(I can't find @user.save statement anywhere is the code.) so, user_with_same_email is already unique since there is no other user with the same email in the database . 但是@user还没有保存到数据库中(我找不到任何地方的@ user.save语句代码。)因此,user_with_same_email已经是唯一的,因为数据库中没有其他用户拥有相同的电子邮件。 Then how does it work? 那它是如何工作的?
I created something similar in the console. 我在控制台中创建了类似的东西。 user_with_same_email.valid? user_with_same_email.valid? returns false (with error "has already been taken"), but user_with_same_email.save still works. 返回false(错误“已经被占用”),但user_with_same_email.save仍然有效。 why? 为什么?
Here's the source code for the be_valid
matcher: 这是be_valid
匹配器的源代码 :
match do |actual|
actual.valid?
end
As you can see, the matcher does not actually save the record, it just calls the method valid?
正如您所看到的,匹配器实际上并不保存记录,它只是调用方法valid?
on the instance. 在实例上。 valid?
checks whether validations will pass or not and if not, sets error messages on the instance. 检查验证是否通过,如果没有,则在实例上设置错误消息。
In the case above, you are first (successfully) saving a user with the same email ( user_with_same_email
), which works since no user with that email has actually been saved yet. 在上面的例子中,您是第一个(成功)使用相同的电子邮件( user_with_same_email
)保存用户,这是有效的,因为没有用户已经实际保存了该电子邮件。 Then you're checking for validation errors on another user instance ( @user
) which has the same email, and that obviously fails even though you have not actually saved the duplicate record. 然后,您正在检查具有相同电子邮件的另一个用户实例( @user
)上的验证错误,即使您实际上没有保存重复记录,这显然也会失败。
Regarding what you get in the console, the problem is likely that save
does not return an error even if it fails. 关于你在控制台中看到,问题很可能是save
即使失败不返回一个错误。 Try using save!
尝试使用save!
instead. 代替。
You can use the shoulda-matchers gem. 你可以使用shoulda-matchers gem。
# spec/models/user_spec.rb
require 'spec_helper'
describe User, 'validations' do
it { should validate_uniqueness_of(:email) }
it { should validate_presence_of(:email) }
it { should validate_format_of(:email).with_message(VALID_EMAIL_REGEX) }
end
Not positive about the last one, but it looks like it should work. 对最后一个没有肯定,但它看起来应该有效。
If you're using clearance, you can use the built-in email_validator
functionality PR here 如果您正在使用许可,则可以在此处使用内置的email_validator
功能PR
# app/models/user.rb
validates :email, presence: true, email: true
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.