使用重复条目测试 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)
我对我的 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)