我想测试用户模型的单一性。
我的User
模型类看起来像:
class User
include Mongoid::Document
field :email, type: String
embeds_one :details
validates :email,
presence: true,
uniqueness: true,
format: {
with: /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z0-9]{2,})\Z/i,
on: :create
},
length: { in: 6..50 }
end
我的rspec测试属于该模型,如下所示:
...
before(:each) do
FactoryGirl.create(:user, email: taken_mail)
end
it "with an already used email" do
expect(FactoryGirl.create(:user, email: taken_mail)).to_not be_valid
end
执行bundle exec rspec
后,它总是引发下一个错误而不是成功传递:
Failure/Error: expect(FactoryGirl.create(:user, email: taken_mail)).to_not be_valid
Mongoid::Errors::Validations:
Problem:
Validation of User failed.
Summary:
The following errors were found: Email is already taken
Resolution:
Try persisting the document with valid data or remove the validations.
如果我使用它,它会成功通过:
it { should validate_uniqueness_of(:email) }
我想使用expect(...)
。有人可以帮帮我吗?
答案 0 :(得分:1)
问题是,您尝试将无效对象持久存储到数据库中,这会引发异常并中断测试(因为电子邮件不是唯一的),甚至在使用expect
方法完成测试之前。 / p>
正确的方法是在这里使用build
而不是create
,它不会在数据库中保留对象,只需在内存中构建记录并允许测试执行工作。因此要解决它:
expect(FactoryGirl.build(:user, email: taken_mail)).to_not be_valid
另请注意,如果您不需要将记录实际保存在数据库中,最好使用build
而不是create
,因为它的操作更便宜,您将会获得相同的结果,除非由于某种原因,您的记录必须保存到数据库中,以便您的测试以您想要的方式工作,例如在示例中保存第一条记录。