我有一个简单的Rails 4应用程序,我试图编写一些测试来检查我的用户注册是否正常工作。 我有一个问题,当我用我的手运行测试用例时,一切正常,但是当我编写一些集成测试并运行它时,它会跳过我的模型的验证,所以我得到了数据库异常喜欢
Minitest::UnexpectedError: ActiveRecord::RecordNotUnique: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_username"
test 'unique username violated' do
params = user_params # it is just a hash with User model attributes
User.new(params).save # saving user first time to violate unique after
params[:email] = 'Test@Email2'
assert_no_difference 'User.count' do
post users_path, user: params
end
assert_template 'users/new'
end
我的验证示例如下:
validates :username, :email, \
uniqueness: {uniqueness: true, message: 'Username&email must be unique'}, \
length: {maximum: 50, message: 'Length must be <= 50'}
不仅是这个验证问题,而且所有其他问题也不在测试中。
如果我在测试中使用类似的东西来验证我的用户对象,那么它应该是假的。
User.new(params).valid?
我的用户#create action如下:
def create
@user = User.new user_params
if @user.save
flash[:success] = 'Welcome to the Sample App!'
redirect_to @user
else
render 'new'
end
end
我的用户#user_params方法:
def user_params
user_group = UserGroup.find_by_name 'administrator'
if user_group.nil?
user_group = UserGroup.new name: 'administrator'
user_group.save
end
{username: 'TestUsername', password: 'TestPassword', \
password_confirmation: 'TestPassword', email: 'Test@Email', \
firstname: 'TestFirstname', lastname: 'TestLastname',user_group: user_group}
end
答案 0 :(得分:0)
Rails验证并没有真正起作用。当你使用:
validates :username, :email, uniqueness: true
您正在为:username
和:email
添加类似但独立的验证。考虑这种情况:
user = User.new
user.valid?
assert(user.errors.has_key?(:username)) # pass
assert(user.errors.has_key?(:email)) # pass
当您使用user.errors.full_messages()
打印出错误时,它会同时包含Email has already been taken
和Username has already been taken
。
但如果你覆盖这样的消息:
validates :username, :email, uniqueness: { message: 'Username&email must be unique' }
你会得到Username&email must be unique
两次,这不是很好。
如果出于某种原因,您确实只需要一个错误,则可以添加自定义验证方法:
validate :uniqueness_of_username_and_email
def uniqueness_of_username_and_email
if User.where("username = ? OR email = ?", username, email).any?
errors.add(:email_username, 'Username&email must be unique')
end
end