Rspec 积分工厂测试中

Rspec integral factories in test

如果我的英语不完美,我深表歉意,但这不是我的母语。
我必须使用 Rails 4.2、Rspec 3.3 和 FactoryGirl 4.5 测试 MySql 数据库。
基本模型的测试是绿色的。当我必须测试包含无法复制的外键的模型时,问题就来了。
起初我有两个模型(dimension.rbfeature.rbtechnical.rb) 每个都有一个来自同一模型的外键 (current.rb):

 #models/dimension.rb
 class Dimension < ActiveRecord::Base 
    belongs_to :current
    has_many :features
    ...
 end

#models/feature.rb
class Feature < ActiveRecord::Base 
   belongs_to :dimension
   has_many :bxes
   ...
end

#models/technical.rb
class Technical < ActiveRecord::Base
   belongs_to :current
   has_many :bxes
   ...
end

这两个模型放在最终模型中(bxe.rb)

#models/bxe.rb
class Bxe < ActiveRecord::Base 
 belongs_to :feature
 belongs_to :technical
 ...
 validates  :technical_id, presence: true
 validates  :feature_id, presence: true 
end

当前型号为:

#models/current.rb
 class Current < ActiveRecord::Base
   has_many :technicals
   has_many :dimensions
   validates :current, presence: true, uniqueness: true
   validates :value,   presence: true, uniqueness: true
 end

工厂如下:

#spec/factories/current.rb
 FactoryGirl.define do
  factory :current do   
   trait :lower do
    current '800A'
    value 800
   end
   trait :higher do
    current '2000A'
    value 2000
   end    
 end
end

#spec/factories/dimension.rb
FactoryGirl.define do 
 factory :dimension do
  ...
  trait :one do
    current {create(:current, :lower)}
  end     
  trait :two do
    current {create(:current, :higher)}
  end     
 end
end

#spec/factories/feature.rb
FactoryGirl.define do
 factory :feature do  
  descr 'MyString'
  dimension { create(:dimension, :one) } 
  ...
 end 
end

#spec/factories/technical.rb
FactoryGirl.define do  
 factory :technical do
  ...  
  trait :A do
    current { create(:current, :lower) }
  end
  trait :L do
    current { create(:current, :higher) }
  end         
 end
end

#spec/factories/bxes.rb
FactoryGirl.define do
  factory :bxe do
   ...
   technical {create(:technical, :A) }
   feature
  end
end

当我 运行 在模型上测试第一个命令 (technical) 运行s 并且工厂创建一个 ID = 1 的当前记录但是第二个 (features) 失败了,因为工厂再次尝试使用相同的数据创建 Current 的记录,模型 current.rb[ 禁止的操作=41=]

#rspec spec/models
2.1.2 :001 > FactoryGirl.create(:bxebusbar, :one)
 ...  Current Exists ... SELECT  1 AS one FROM `currents` WHERE `currents`.`current` = BINARY '800A' LIMIT 1
 ...  INSERT INTO `currents` (`current`, `value`, `created_at`, `updated_at`) VALUES ('800A', 800, ..., ...)
...  INSERT INTO `technicals` (..., `current_id`, ..., `created_at`, `updated_at`) VALUES (..., 1, ..., ...)
...  Current Exists ...  SELECT  1 AS one FROM `currents` WHERE `currents`.`current` = BINARY '800A' LIMIT 1
...  ActiveRecord::RecordInvalid: Validation failed: Current has already been taken, Value has already been taken

我认为可以通过仅创建一次当前记录然后在 technicalfeatures 工厂中使用它来解决问题,现实中会发生什么,但我不知道该怎么做。 有什么建议吗?谢谢

您可以使用sequences生成不会重复的值。另一种选择是使用 DatabaseCleaner 并将其设置为在每次测试后清理数据库。

第一个选项:

FactoryGirl.define do
  factory :current do   
   trait :lower do
    sequence :current do { |n| "#{n}A" }
    sequence :value do {|n| "#{n}" }
   end    
 end
end

或设置数据库清理器:Database cleaner