簡體   English   中英

帶有transactional_fixtures = true的Rspec引發唯一性錯誤

[英]Rspec with transactional_fixtures=true throws uniqueness errors

我正在測試我的API,使用Grape和Rails以及RSpec進行構建,並且遇到很多唯一性驗證錯誤。

我在每次測試后使用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 gem,但是得到了相同的錯誤(在嘗試DatabaseCleaner之前禁用了use_transactional_fixtures )。

注意:我正在使用Postgres和apartment 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

實際上,數據庫已清除,因此在Database.clean之后, Contact.allClient.all為空。 這令人困惑,因為否則不應該發生驗證錯誤?

我想到了。 感謝這個答案: 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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM