【问题标题】:Rspec tests for checking uniqueness用于检查唯一性的 Rspec 测试
【发布时间】:2012-10-02 01:47:58
【问题描述】:

这是检查电子邮件唯一性的 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

正如作者所说,我添加了

class User < ActiveRecord::Base
  .
  .
  .
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: true
end

到我的用户模型并且测试通过。

但是@user 还没有保存到数据库中(我在代码的任何地方都找不到@user.save 语句。)所以,user_with_same_email 已经是唯一的,因为在数据库。那么它是如何工作的呢?

我在控制台中创建了类似的东西。 user_with_same_email.valid?返回 false (错误“已被采取”),但 user_with_same_email.save 仍然有效。为什么?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 rspec


    【解决方案1】:

    您可以使用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
    

    对最后一个不太肯定,但看起来应该可以。

    如果你使用间隙,你可以使用内置的email_validator功能PR here

    # app/models/user.rb
    validates :email, presence: true, email: true
    

    【讨论】:

      【解决方案2】:

      这是be_valid 匹配器的source code

      match do |actual|
        actual.valid?
      end
      

      如您所见,匹配器实际上并没有保存记录,它只是调用实例上的方法valid?valid? 检查验证是否通过,如果没有,则在实例上设置错误消息。

      在上述情况下,您首先(成功地)保存了具有相同电子邮件 (user_with_same_email) 的用户,因为实际上还没有使用该电子邮件的用户保存。然后,您正在检查具有相同电子邮件的另一个用户实例 (@user) 上的验证错误,即使您实际上没有保存重复记录,这显然也会失败。

      关于您在控制台中获得的内容,问题很可能是save 即使失败也不会返回错误。尝试改用save!

      【讨论】:

      • 哦,我明白了。我以为情况正好相反。现在一切都说得通了。谢谢:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多