使用重复条目测试 Rails 模型唯一性

Testing Rails model uniqueness with duplicate entry

我对我的 Rails 数据库有一个限制,以强制使用唯一的用户名,并且我在每个模型测试开始时创建一个用户。我正在尝试使用与第一个用户名相同的用户名创建第二个用户,我希望这无效,但它返回时有效。

我尝试调整代码以在生成新用户时使用新的、保存的和创建的方法,但没有成功。

注册模型:

class Registration < ApplicationRecord
  @username_length = (3..20)
  @password_requirements = /\A
    (?=.{8,}) # Password must be at least 8 characters
    (?=.*\d) # Password must contain at least one number
    (?=.*[a-z]) # Password must contain at least one lowercase letter
    (?=.*[A-Z]) # Password must contain at least one capital letter
    # Password must have special character
    (?=.*[['!', '@', '#', '$', '%', '^', '&']])
  /x

  validates :username, length: @username_length, uniqueness: true
  validates :password, format: @password_requirements
  validates :email, uniqueness: true
  has_secure_password
  has_secure_token :auth_token

  def invalidate_token
    self.update_columns(auth_token: nil)
  end

  def self.validate_login(username, password)
    user = Registration.find_by(username: username)
    if user && user.authenticate(password)
      user
    end
  end
end

注册测试:

require 'rails_helper'

RSpec.describe Registration, type: :model do
  before do
    @user = Registration.new(
      username: '1234',
      password: 'abcdeF7#',
      email: 'test@test.com',
      name: 'One'
    )
  end
  it 'should not be valid if the username is already taken' do
    @user.save!(username: '1234')
    expect(@user).not_to be_valid
  end
end

我希望这个测试能够通过,因为它是一个重复的用户名。

正如 fabio 所说,您没有第二个注册对象来检查唯一性。 您刚刚检查了您保存的@user 是否有效,它始终有效并保存在数据库中。要检查您的唯一性验证,您可以这样做 -

RSpec.describe Registration, type: :model do
  before do
    @user = Registration.create(
      username: '1234',
      password: 'abcdeF7#',
      email: 'test@test.com',
      name: 'One'
    )
    @invalid_user = @user.dup
    @invalid_user.email = "test1@test.com"
  end
  it 'should not be valid if the username is already taken' do
    expect(@invalid_user.valid?).should be_falsey
  end
end

@user.save! 甚至在达到 Fabio

评论中提到的预期之前就会引发错误

此外,如果测试数据库级别的约束对您很重要,您可以这样做:

expect { @user.save validate: false }.to raise_error(ActiveRecord::RecordNotUnique)