[英]Rspec with transactional_fixtures=true throws uniqueness errors
I'm testing my API, build with Grape and Rails, with RSpec and get a lot of uniqueness validation errors. 我正在测试我的API,使用Grape和Rails以及RSpec进行构建,并且遇到很多唯一性验证错误。
I'm using config.use_transactional_fixtures = true
to rollback the database after each test, but I'm getting this errors: 我在每次测试后使用
config.use_transactional_fixtures = true
来回滚数据库,但出现此错误:
7) API GET /api/v1/quotations returns 200 when there is at least one quotation
Failure/Error: FactoryGirl.create(:quotation)
ActiveRecord::RecordInvalid:
Validation failed: Number has already been taken
# ./spec/requests/api/quotations_spec.rb:56:in `block (3 levels) in <top (required)>'
I think the problem is, that my models have transitive dependencies: 我认为问题是我的模型具有传递依赖项:
Clients
have Contacts
and Contacts
have Quotations. Clients
有Contacts
, Contacts
有报价。 So when creating a quotation, a corresponding contact with a corresponding client should be created. 因此,在创建报价时,应创建与相应客户的相应联系人。 And a quotation always belongs to a
Request
. 引号始终属于
Request
。 But it seems, that FactoryGirl doesn't create new instances? 但是似乎FactoryGirl不会创建新实例吗?
The validations error does not belong to a quotation. 验证错误不属于引号。 If I remove the uniqueness validation on the quotation model, I get the same error.
如果删除报价模型上的唯一性验证,则会收到相同的错误。 Actually, it belongs to the client model.
实际上,它属于客户端模型。
It seems, that not all tables get truncated? 似乎不是所有表都被截断了吗? I event tried out DatabaseCleaner gem, but get the same errors (disabled
use_transactional_fixtures
before tried DatabaseCleaner). 我事件尝试了DatabaseCleaner gem,但是得到了相同的错误(在尝试DatabaseCleaner之前禁用了
use_transactional_fixtures
)。
Note: I'm using Postgres and the apartment gem for multi-tenancy. 注意:我正在使用Postgres和apartment gem进行多租户。
That are my factories: 那是我的工厂:
Client factory 客户工厂
FactoryGirl.define do
factory :client do
number Faker::Number.number(8)
company Faker::Company.name
address1 Faker::Address.street_address
address2 Faker::Address.secondary_address
city Faker::Address.city
zip Faker::Address.zip
country Faker::Address.country
tax '19'
email Faker::Internet.email
phone Faker::PhoneNumber.phone_number
web Faker::Internet.url
end
end
Contact factory 联系工厂
FactoryGirl.define do
factory :contact do
title Faker::Name.title
name Faker::Name.name
surname Faker::Name.last_name
department Faker::Commerce.department
email Faker::Internet.email
phone Faker::PhoneNumber.phone_number
password 'secret'
password_confirmation 'secret'
client
end
end
Quotation factory 报价厂
FactoryGirl.define do
factory :quotation do
number Faker::Number.number(8)
title Faker::Lorem.word
payable Faker::Lorem.sentence
request
contact
end
end
Request factory 要求工厂
FactoryGirl.define do
factory :request do
number Faker::Number.number(8)
title Faker::Lorem.word
content Faker::Lorem.sentence
contact
end
end
Part of my quotations_spec.rb
我的
quotations_spec.rb
require 'spec_helper'
describe API do
include Rack::Test::Methods
def app
API
end
####################################################################################################################
# Authentication
####################################################################################################################
let(:url) { 'http://testing.domain.com' }
let!(:access_token) do
user = FactoryGirl.create(:user)
api_key = FactoryGirl.create(:api_key_session, foreign_id: user.id)
api_key.access_token
end
describe 'GET /api/v1/quotations' do
it 'returns 401 when unauthorized' do
get "#{url}/api/v1/quotations"
expect(last_response.status).to eq 401
end
end
####################################################################################################################
# GET quotations
####################################################################################################################
describe 'GET /api/v1/quotations' do
#----------------------------------------------------------------------------------------------------------------#
it 'returns 404 when quotations not found' do
header 'X-Access-Key', access_token
get "#{url}/api/v1/quotations"
expect(last_response.status).to eq 404
end
#----------------------------------------------------------------------------------------------------------------#
it 'returns 200 when there is at least one quotation' do
FactoryGirl.create(:quotation)
header 'X-Access-Key', access_token
get "#{url}/api/v1/quotations"
expect(last_response.status).to eq 200
end
#----------------------------------------------------------------------------------------------------------------#
end
end
I switched to DatabaseCleaner and tried to debug this: 我切换到DatabaseCleaner并尝试调试它:
config.after(:each) do
puts
puts '####'
puts Client.all
puts '####'
puts Contact.all
puts '####'
puts
DatabaseCleaner.clean
puts
puts '####'
puts Client.all
puts '####'
puts Contact.all
puts '####'
puts
# Reset tentant back to `public`
Apartment::Database.reset
end
Actually, the database gets cleaned, so Contact.all
and Client.all
is empty after Database.clean
. 实际上,数据库已清除,因此在
Database.clean
之后, Contact.all
和Client.all
为空。 This is confusing, because otherwise the validation errors shouldn't occur? 这令人困惑,因为否则不应该发生验证错误?
I figured it out. 我想到了。 Thanks to this answer: https://stackoverflow.com/a/16726614/1184904
感谢这个答案: https : //stackoverflow.com/a/16726614/1184904
I have to replace the unique fields with sequences like this: 我必须用以下序列替换唯一字段:
FactoryGirl.define do
factory :user do
name Faker::Name.name
surname Faker::Name.last_name
sequence :email do |n|
"foo#{n}@bar.de"
end
password 'secret'
password_confirmation 'secret'
end
end
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.