2014-06-23 37 views
0

我正在使用RSpec測試我的API,使用Grape和Rails進行構建,並獲得大量唯一性驗證錯誤。Rspec with transactional_fixtures = true會拋出唯一性錯誤

我使用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)>' 

我認爲這個問題是,我的模型有傳遞依賴:

ClientsContactsContacts有報價。 因此,在創建報價時,應該創建與相應客戶端的相應聯繫人。並且報價總是屬於Request。但是,FactoryGirl似乎並沒有創建新的實例?

驗證錯誤不是屬於報價單。如果刪除報價模型的唯一性驗證,我會得到相同的錯誤。實際上,它屬於客戶端模型。

看來,並非所有的表都被截斷?我的事件嘗試了DatabaseCleaner的寶石,但得到相同的錯誤(在嘗試DatabaseCleaner之前禁用use_transactional_fixtures)。

注:我使用Postgres和公寓gem進行多租戶。

這是我的工廠:

客戶工廠

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 

工廠聯繫

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 

報價工廠

FactoryGirl.define do 

    factory :quotation do 
    number Faker::Number.number(8) 
    title Faker::Lorem.word 
    payable Faker::Lorem.sentence 
    request 
    contact 
    end 

end 

要求在工廠

FactoryGirl.define do 

    factory :request do 
    number Faker::Number.number(8) 
    title Faker::Lorem.word 
    content Faker::Lorem.sentence 
    contact 
    end 

end 

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 

更新的第1部分

我切換到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 

實際上,數據庫得到清潔,所以Contact.allClient.allDatabase.clean後空。這很混亂,否則驗證錯誤不應該發生?

回答

0

我想通了。多虧了這樣的回答:https://stackoverflow.com/a/16726614/1184904

我有序列以替換唯一領域是這樣的:

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