gpt4 book ai didi

ruby-on-rails - Rspec + Postgresql9.1 违反非空约束?

转载 作者:行者123 更新时间:2023-11-29 12:14:26 29 4
gpt4 key购买 nike

我正在使用 postgresql 9.1 运行 rails 3.1.3 并使用 Rspec 进行测试。这实际上是一个基于 railstutorial 的测试应用程序,作为我学习 rails 的一部分。

我的问题是 spec/models/employee_spec.rb 测试。到目前为止,有 34 个示例,除了三个之外,所有示例都通过了,但由于非空约束,它们都失败了。以下是失败的测试:

it "should create a new instance given valid attributes" do
Employee.create!(@attr)
end (------ the Employee.create!(@attr) seems to be the problem)

it "should reject duplicate email addresses" do
# Put an employee with a given email address into the database.
Employee.create!(@attr)

employee_with_duplicate_email = Employee.new(@attr)

employee_with_duplicate_email.should_not be_valid
end

it "should reject email addresses identical up to case" do
upcased_email = @attr[:email].upcase

Employee.create!(@attr.merge(:email => upcased_email))

employee_with_upcase_email = Employee.new(@attr)

employee_with_upcase_email.should_not be_valid
end

希望阅读这篇文章的人中的一个,如果不是太长,可以给我一些关于如何解决这个问题的指示。(我可以进入 postgresql 并更改属性,使其接受空值,但是我想 rspec 应该能够处理非空约束)

好吧,非常感谢您提供的任何帮助、指示和指导。

汤姆。

表的架构:

# == Schema Information
#
# Table name: employees
#
# id :integer not null, primary key
# first_name :string(255) not null
# last_name :string(255) not null
# mi :text
# marital_status :string(255) not null
# gender :string(255) not null
# birth_date :date default(Sat, 20 Aug 1949), not null
# hire_date :date not null
# term_date :date
# primary_position :string(255) not null
# trained_position :string(255)
# email :string(255) not null
# active :boolean default(TRUE), not null
# address1 :string(255) not null
# address2 :string(255)
# city :string(255) not null
# zip_code :string(255) not null
# state :string(255) not null
# emp_home_ph :string(255)
# emp_mobile_ph :string(255)
# emer_contact_first_name :string(255)
# emer_contact_last_name :string(255)
# emer_contact_relationship :string(255)
# emer_contact_ph :string(255)
# created_at :datetime
# updated_at :datetime
#

规范文件(~/spec/models/employee_spec.rb):

require 'spec_helper'

describe Employee do

before(:each) do
@attr = { :first_name => "Teress", :last_name => "Pottle", :mi => "null",
:marital_status => "Single", :gender => "Female", :birth_date => '1987-04-20',
:hire_date => '2002-01-01', :term_date => "null", :active => "true",
:primary_position => "Job Coach", :trained_position => "null", :email =>
"tpottle@example.com", :address1 => "1 First Ave", :address2 => "null", :city =>
"Frave", :zip_code => "54806", :state => "WI", :emp_home_ph => "null",
:emp_mobile_ph => "null", :emer_contact_first_name => "null",
:emer_contact_last_name => "null", :emer_contact_relationship => "null",
:emer_contact_ph => "null" }
end

it "should create a new instance given valid attributes" do
Employee.create!(@attr)
end

it "should require a first_name" do
no_first_name = Employee.new(@attr.merge(:first_name => ""))
no_first_name.should_not be_valid
end

it "should reject first_name that is too long" do
long_name = "a" * 26
long_first_name = Employee.new(@attr.merge(:first_name => long_name))
long_first_name.should_not be_valid
end

it "should require a last_name" do
no_last_name = Employee.new(@attr.merge(:last_name => ""))
no_last_name.should_not be_valid
end

it "should reject a last_name that is too long" do
long_name = "a" * 26
long_last_name = Employee.new(@attr.merge(:last_name => long_name))
long_last_name.should_not be_valid
end

it "should require a marital_status" do
no_marital_status = Employee.new(@attr.merge(:marital_status => ""))
no_marital_status.should_not be_valid
end

it "should require a gender" do
no_gender = Employee.new(@attr.merge(:gender => ""))
no_gender.should_not be_valid
end

it "should require a birth_date" do
no_birth_date = Employee.new(@attr.merge(:birth_date => ""))
no_birth_date.should_not be_valid
end

it "should require a hire_date" do
no_hire_date = Employee.new(@attr.merge(:hire_date => ""))
no_hire_date.should_not be_valid
end

it "should require a primary_position" do
no_primary_position = Employee.new(@attr.merge(:primary_position => ""))
no_primary_position.should_not be_valid
end

it "should require a email" do
no_email = Employee.new(@attr.merge(:email => ""))
no_email.should_not be_valid
end

it "should require an 'active' setting" do
no_active_setting = Employee.new(@attr.merge(:active => ""))
no_active_setting.should_not be_valid
end

it "should require an address1" do
no_address1 = Employee.new(@attr.merge(:address1 => ""))
no_address1.should_not be_valid
end

it "should require a city" do
no_city = Employee.new(@attr.merge(:city => ""))
no_city.should_not be_valid
end

it "should require a zip_code" do
no_zip_code = Employee.new(@attr.merge(:zip_code => ""))
no_zip_code.should_not be_valid
end

it "should require a state" do
no_state = Employee.new(@attr.merge(:state => ""))
no_state.should_not be_valid
end

it "should accept valid email addresses" do
addresses = %w[user@foo.com THE_USER@foo.bar.org first.last@foo.jp]
addresses.each do |address|
valid_email_employee = Employee.new(@attr.merge(:email => address))
valid_email_employee.should be_valid
end
end

it "should reject invalid email addresses" do
addresses = %w[user@foo,com user_at_foo.org example.user@foo.]
addresses.each do |address|
invalid_email_employee = Employee.new(@attr.merge(:email => address))
invalid_email_employee.should_not be_valid
end
end

it "should reject duplicate email addresses" do
# Put an employee with a given email address into the database.
Employee.create!(@attr)
employee_with_duplicate_email = Employee.new(@attr)
employee_with_duplicate_email.should_not be_valid
end

it "should reject email addresses identical up to case" do
upcased_email = @attr[:email].upcase
Employee.create!(@attr.merge(:email => upcased_email))
employee_with_upcase_email = Employee.new(@attr)
employee_with_upcase_email.should_not be_valid
end
end

员工类(~/app/models/employee.rb):

 class Employee < ActiveRecord::Base

attr_accessor :first_name, :last_name, :mi, :marital_status, :gender, :birth_date,
:hire_date, :term_date, :primary_position, :trained_position, :email, :active,
:address1, :address2, :city, :zip_code, :state, :emp_home_ph, :emp_mobile_ph,
:emer_contact_first_name, :emer_contact_last_name, :emer_contact_relationship,
:emer_contact_ph

email_regex = /([\w+.]+)@[a-z0-9\-.]+\.[a-z]+/i
date_regex = /^[0-9]{4}[-][0-9]{2}[-][0-9]{2}$/

validates(:marital_status, :gender, :primary_position, :active, :address1, :city,
:zip_code, :state, :presence => true)
validates(:first_name, :last_name, :presence => true,
:length => { :maximum => 25 })
validates(:birth_date, :hire_date, :presence => true,
:format => { :with => date_regex })
validates(:email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false})
end

当我运行 rspec 时会发生什么:

loading autotest/rails_rspec2
/home/tom/.rvm/rubies/ruby-1.9.3-p0/bin/ruby -rrubygems -S /home/tom/.rvm/gems
/ruby-1.9.3-p0@latest/gems/rspec-core-2.7.1/exe/rspec --tty
'/home/tom/rails_projects/tracking /spec/controllers/employees_controller_spec.rb'
'/home/tom/rails_projects/tracking/spec/controllers/pages_controller_spec.rb' '/home
/tom/rails_projects/tracking/spec/models/employee_spec.rb' '/home/tom/rails_projects
/tracking/spec/requests/layout_links_spec.rb'
........F.................FF......

Failures:

1) Employee should create a new instance given valid attributes
Failure/Error: Employee.create!(@attr)
ActiveRecord::StatementInvalid:
PGError: ERROR: null value in column "first_name" violates not-null constraint
: INSERT INTO "employees" ("active", "address1", "address2", "birth_date",
"city", "created_at", "email", "emer_contact_first_name",
"emer_contact_last_name", "emer_contact_ph", "emer_contact_relationship",
"emp_home_ph", "emp_mobile_ph", "first_name", "gender", "hire_date", "last_name",
"marital_status", "mi", "primary_position", "state", "term_date",
"trained_position", "updated_at", "zip_code")
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16,
$17, $18, $19, $20, $21, $22, $23, $24, $25) RETURNING "id"
# ./spec/models/employee_spec.rb:42:in `block (2 levels) in <top (required)>'

2) Employee should reject duplicate email addresses
Failure/Error: Employee.create!(@attr)
ActiveRecord::StatementInvalid:
PGError: ERROR: null value in column "first_name" violates not-null constraint
: INSERT INTO "employees" ("active", "address1", "address2", "birth_date", "city",
"created_at", "email", "emer_contact_first_name", "emer_contact_last_name",
"emer_contact_ph", "emer_contact_relationship", "emp_home_ph", "emp_mobile_ph",
"first_name", "gender", "hire_date", "last_name", "marital_status", "mi",
"primary_position", "state", "term_date", "trained_position", "updated_at",
"zip_code")
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16,
$17, $18, $19, $20, $21, $22, $23, $24, $25) RETURNING "id"
# ./spec/models/employee_spec.rb:140:in `block (2 levels) in <top (required)>'

3) Employee should reject email addresses identical up to case
Failure/Error: Employee.create!(@attr.merge(:email => upcased_email))
ActiveRecord::StatementInvalid:
PGError: ERROR: null value in column "first_name" violates not-null constraint
: INSERT INTO "employees" ("active", "address1", "address2", "birth_date", "city",
"created_at", "email", "emer_contact_first_name", "emer_contact_last_name",
"emer_contact_ph", "emer_contact_relationship", "emp_home_ph", "emp_mobile_ph",
"first_name", "gender", "hire_date", "last_name", "marital_status", "mi",
"primary_position", "state", "term_date", "trained_position", "updated_at",
"zip_code") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14,
$15, $16,$17, $18, $19, $20, $21, $22, $23, $24, $25) RETURNING "id"
# ./spec/models/employee_spec.rb:147:in `block (2 levels) in <top (required)>'

Finished in 19.24 seconds
34 examples, 3 failures

Failed examples:

rspec ./spec/models/employee_spec.rb:41 # Employee should create a new instance given
valid attributes
rspec ./spec/models/employee_spec.rb:138 # Employee should reject duplicate email
addresses
rspec ./spec/models/employee_spec.rb:145 # Employee should reject email addresses
identical up to case

最佳答案

你的问题不在于你的测试,你的问题在于你的 Employee 类。您的类(class)以此开头:

class Employee < ActiveRecord::Base

attr_accessor :first_name, :last_name, :mi, :marital_status, :gender, :birth_date,
:hire_date, :term_date, :primary_position, :trained_position, :email, :active,
:address1, :address2, :city, :zip_code, :state, :emp_home_ph, :emp_mobile_ph,
:emer_contact_first_name, :emer_contact_last_name, :emer_contact_relationship,
:emer_contact_ph

但您不需要或不想在这里使用 attr_accessor。普通对象属性(由 attr_accessor 创建)与 ActiveRecord 属性不同。 ActiveRecord 将检查表的结构并为数据库支持的属性创建自己的内部存储,并为这些属性创建一套访问器和修改器方法;在内部,ActiveRecord 将使用这些访问器方法来查看对象中的内容。然后,您使用 attr_accessor 将列声明为对象属性,并且 attr_accessor 创建自己的访问器和更改器方法来替换 ActiveRecord 的。结果是 object.first_name 将在 object 中寻找 @first_name 实例变量但是不会有这样的东西, Employee.create 将在 ActiveRecord 的属性中设置 first_name不是 @first_name 实例值。

解决方案是去掉类中的 attr_accessor 语句。然后阅读Rails Guides与您的教程并行。

关于ruby-on-rails - Rspec + Postgresql9.1 违反非空约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8453172/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com