简体   繁体   English

RSpec Mongoid唯一性验证

[英]rspec mongoid validation of uniqueness

I would like to test the uniquness of User model. 我想测试用户模型的唯一性。

My User model class looks like: 我的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

My rspec test which belongs to the model looks like: 我属于该模型的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

After I executed bundle exec rspec it always raises the next error instead of passed with success: 在执行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.

If I use this it passes with success: 如果我使用它,则成功通过:

it { should validate_uniqueness_of(:email) }

I would like to use expect(...) . 我想使用expect(...) Can anybody help me out? 有人可以帮我吗?

The issue is you are trying to persist an invalid object into the database, which throws an exception and breaks the test (because email is not unique), before even the test is done using the expect method. 问题是您试图将无效对象持久保存到数据库中,这会引发异常并破坏测试(因为电子邮件不是唯一的),甚至在使用expect方法完成测试之前也是如此。

The correct way is to use build here instead of create , which doesn't persist the object in the database, by building the record only in memory and allowing your test to do its job. 正确的方法是在此处使用build而不是create ,因为它仅在内存中构建记录并允许您的测试来完成工作,所以create不会将对象保留在数据库中。 Therefore to fix it: 因此要解决它:

expect(FactoryGirl.build(:user, email: taken_mail)).to_not be_valid

Also note that is better to use build rather than create if you don't need to actually save the record in the database, since it's a cheaper operation and you will get the same outcome, unless for some reason your record must be saved to the database for your tests to work in a way you want them, such as saving the first record in in your example. 还要注意,如果您不需要实际将记录保存在数据库中,则使用build而不是create更好,因为这是一种更便宜的操作,并且您将获得相同的结果,除非出于某种原因必须将记录保存到数据库中。数据库以使您的测试以您希望的方式工作,例如在示例中保存第一条记录。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM