Rspec 从 Sqlite 迁移到 Postgresql 后测试失败
Rspec Test Fail After Migrating from Sqlite to Postgresql
我在 Rails + Rspec + Capybara + FactoryGirl + DatabaseCleaner 上使用 Cloud 9 + Ruby。到目前为止,我一直在使用 sqlite 进行开发,并使用 运行 跨图表功能,而这些功能不适用于 sqlite。所以我迁移到使用 Postgresql。
现在,当我 运行 我的 rspec 测试失败时。我可以恢复到使用 sqlite 和测试 运行 就可以了。
这是我收到的错误之一:
Failures:
2) Property creation has been completed successfully
Failure/Error: @property = FactoryGirl.create(:property)
ActiveRecord::InvalidForeignKey:
PG::ForeignKeyViolation: ERROR: insert or update on table "properties" violates foreign key constraint "fk_rails_680868ce5b"
DETAIL: Key (property_type_id)=(1) is not present in table "property_types".
: INSERT INTO "properties" ("address", "city", "state", "zip", "property_type_id", "user_id", "created_at", "updated_at") VALUES (, , , , , , , ) RETURNING "id"
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/evaluation.rb:15:in `create'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `tap'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `result'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory.rb:42:in `run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:28:in `run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/features/property_spec.rb:10:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::ForeignKeyViolation:
# ERROR: insert or update on table "properties" violates foreign key constraint "fk_rails_680868ce5b"
# DETAIL: Key (property_type_id)=(1) is not present in table "property_types".
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
我认为这个错误正在发生,因为 1 的 property_type_id 在创建时 property_types table 中不存在 ID 为 1 的。相反,property_types 的 ID 是 2。似乎 ID 列在每个示例后都没有重置回 1。
这是我的 rails_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rails'
include Warden::Test::Helpers
Warden.test_mode!
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.before(:suite) { DatabaseCleaner.clean_with(:truncation) }
config.before(:each) { DatabaseCleaner.strategy = :transaction }
config.before(:each, :js => true) { DatabaseCleaner.strategy = :truncation }
config.before(:each) { DatabaseCleaner.start }
config.after(:each) { DatabaseCleaner.clean }
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include FactoryGirl::Syntax::Methods
end
这是 Database.yml 文件:
default: &default
adapter: postgresql
encoding: unicode
pool: 5
username: ubuntu
password: xxxxxxxx
template: template0
development:
<<: *default
database: app_development
test:
<<: *default
database: app_test
production:
<<: *default
database: app_production
这是失败的测试之一:
require 'rails_helper'
describe 'Property' do
describe 'creation' do
it "has been completed successfully" do
@user = FactoryGirl.create(:user)
login_as(@user, :scope => :user)
FactoryGirl.create(:property_type)
@property = FactoryGirl.create(:property)
visit new_property_path
fill_in "property_address", with: @property.address
fill_in "property_city", with: @property.city
fill_in "property_state", with: @property.state
fill_in "property_zip", with: @property.zip
fill_in "property_units", with: @property.units
click_button "Save"
expect(@property.reload.address).to eq(@property.address)
expect(@property.reload.city).to eq(@property.city)
expect(@property.reload.state).to eq(@property.state)
expect(@property.reload.zip).to eq(@property.zip)
expect(@property.reload.units).to eq(@property.units)
end
end
这是 属性 工厂:
FactoryGirl.define do
factory :property do
address "111 Test Dr"
city "Test"
state "TS"
zip "999999"
property_type_id 1
user_id 1
end
end
这是用户工厂:
FactoryGirl.define do
factory :user do
email "tester@tester.com"
first_name "Test"
last_name "Test"
password "abcd1234"
password_confirmation "abcd1234"
end
end
这是 属性 类型工厂:
FactoryGirl.define do
factory :property_type do
name "Single Family"
end
end
任何帮助将不胜感激,因为我已经研究了这个问题好几天了。
在属性Factory中,property_type_id总是引用1,如果在property_typetable.[=11中找不到会引发外键错误=]
如果属性 与property_type 有关系,您可以将其更改为使用关联,它将动态创建property_type。
FactoryGirl.define do
factory :property do
address "111 Test Dr"
city "Test"
state "TS"
zip "999999"
property_type
user_id 1
end
end
或者您可以在测试数据库中保留一个 ID 为 1 的 property_type 记录。
我在 Rails + Rspec + Capybara + FactoryGirl + DatabaseCleaner 上使用 Cloud 9 + Ruby。到目前为止,我一直在使用 sqlite 进行开发,并使用 运行 跨图表功能,而这些功能不适用于 sqlite。所以我迁移到使用 Postgresql。
现在,当我 运行 我的 rspec 测试失败时。我可以恢复到使用 sqlite 和测试 运行 就可以了。
这是我收到的错误之一:
Failures:
2) Property creation has been completed successfully
Failure/Error: @property = FactoryGirl.create(:property)
ActiveRecord::InvalidForeignKey:
PG::ForeignKeyViolation: ERROR: insert or update on table "properties" violates foreign key constraint "fk_rails_680868ce5b"
DETAIL: Key (property_type_id)=(1) is not present in table "property_types".
: INSERT INTO "properties" ("address", "city", "state", "zip", "property_type_id", "user_id", "created_at", "updated_at") VALUES (, , , , , , , ) RETURNING "id"
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/evaluation.rb:15:in `create'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:12:in `block in result'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `tap'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy/create.rb:9:in `result'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory.rb:42:in `run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:29:in `block in run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/factory_runner.rb:28:in `run'
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/strategy_syntax_method_registrar.rb:20:in `block in define_singular_strategy_method'
# ./spec/features/property_spec.rb:10:in `block (3 levels) in <top (required)>'
# ------------------
# --- Caused by: ---
# PG::ForeignKeyViolation:
# ERROR: insert or update on table "properties" violates foreign key constraint "fk_rails_680868ce5b"
# DETAIL: Key (property_type_id)=(1) is not present in table "property_types".
# /usr/local/rvm/gems/ruby-2.3.0/gems/factory_girl-4.8.0/lib/factory_girl/configuration.rb:18:in `block in initialize'
我认为这个错误正在发生,因为 1 的 property_type_id 在创建时 property_types table 中不存在 ID 为 1 的。相反,property_types 的 ID 是 2。似乎 ID 列在每个示例后都没有重置回 1。
这是我的 rails_helper.rb:
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'spec_helper'
require 'rspec/rails'
require 'capybara/rails'
include Warden::Test::Helpers
Warden.test_mode!
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
config.use_transactional_fixtures = false
config.before(:suite) { DatabaseCleaner.clean_with(:truncation) }
config.before(:each) { DatabaseCleaner.strategy = :transaction }
config.before(:each, :js => true) { DatabaseCleaner.strategy = :truncation }
config.before(:each) { DatabaseCleaner.start }
config.after(:each) { DatabaseCleaner.clean }
config.infer_spec_type_from_file_location!
config.filter_rails_from_backtrace!
config.include FactoryGirl::Syntax::Methods
end
这是 Database.yml 文件:
default: &default
adapter: postgresql
encoding: unicode
pool: 5
username: ubuntu
password: xxxxxxxx
template: template0
development:
<<: *default
database: app_development
test:
<<: *default
database: app_test
production:
<<: *default
database: app_production
这是失败的测试之一:
require 'rails_helper'
describe 'Property' do
describe 'creation' do
it "has been completed successfully" do
@user = FactoryGirl.create(:user)
login_as(@user, :scope => :user)
FactoryGirl.create(:property_type)
@property = FactoryGirl.create(:property)
visit new_property_path
fill_in "property_address", with: @property.address
fill_in "property_city", with: @property.city
fill_in "property_state", with: @property.state
fill_in "property_zip", with: @property.zip
fill_in "property_units", with: @property.units
click_button "Save"
expect(@property.reload.address).to eq(@property.address)
expect(@property.reload.city).to eq(@property.city)
expect(@property.reload.state).to eq(@property.state)
expect(@property.reload.zip).to eq(@property.zip)
expect(@property.reload.units).to eq(@property.units)
end
end
这是 属性 工厂:
FactoryGirl.define do
factory :property do
address "111 Test Dr"
city "Test"
state "TS"
zip "999999"
property_type_id 1
user_id 1
end
end
这是用户工厂:
FactoryGirl.define do
factory :user do
email "tester@tester.com"
first_name "Test"
last_name "Test"
password "abcd1234"
password_confirmation "abcd1234"
end
end
这是 属性 类型工厂:
FactoryGirl.define do
factory :property_type do
name "Single Family"
end
end
任何帮助将不胜感激,因为我已经研究了这个问题好几天了。
在属性Factory中,property_type_id总是引用1,如果在property_typetable.[=11中找不到会引发外键错误=]
如果属性 与property_type 有关系,您可以将其更改为使用关联,它将动态创建property_type。
FactoryGirl.define do
factory :property do
address "111 Test Dr"
city "Test"
state "TS"
zip "999999"
property_type
user_id 1
end
end
或者您可以在测试数据库中保留一个 ID 为 1 的 property_type 记录。