【问题标题】:rspec mongoid validation of uniquenessrspec mongoid 唯一性验证
【发布时间】:2014-10-24 14:39:37
【问题描述】:

我想测试用户模型的唯一性。

我的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(...)。谁能帮帮我?

【问题讨论】:

  • 如果您尝试:expect(FactoryGirl.build(:user, email: taken_mail)).to_not be_valid 会怎样?使用构建而不是创建
  • 它工作正常并且测试通过但我不知道为什么当我使用create 方法时会出现错误。如果我想使用FactoryGirl.create(...) 怎么办?如果您将其留在答案中,我会给您重点。

标签: ruby-on-rails validation rspec mongoid validates-uniqueness-of


【解决方案1】:

问题是您试图将无效对象持久化到数据库中,这会引发异常并中断测试(因为电子邮件不是唯一的),甚至在使用 expect 方法完成测试之前。

正确的方法是在这里使用build 而不是create,它不会将对象保存在数据库中,方法是仅在内存中构建记录并允许您的测试完成其工作。因此修复它:

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

还请注意,如果您不需要将记录实际保存在数据库中,最好使用build 而不是create,因为这是一种更便宜的操作,并且您将获得相同的结果,除非出于某种原因您的记录必须保存到数据库中,以便您的测试以您希望的方式工作,例如在您的示例中保存第一条记录。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-01
    • 2011-10-23
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    • 1970-01-01
    相关资源
    最近更新 更多