2014-04-09 21 views
4

長時間閱讀器,但第一次在這裏的海報:)所以爲什麼'FactoryGirl.lint'給出InvalidFactoryError?

在過去幾天我一直在建立FactoryGirl。

Language.find_or_create_by_code('en') 

有了:

Language.find_by_code('en') || create(:language) 

因爲第一選項創建只有一個語言對象

昨天我通過更換改變了一些工廠(主要是我用戶品牌工廠)代碼屬性填入;而第二個使用語言工廠創建對象(並因此填寫工廠中指定的所有屬性)

現在,當我運行我的測試它立即失敗Factory.lint,說明我的用戶(和admin_user)工廠無效。恢復上面的代碼並沒有解決這個問題,FactoryGirl.lint提供的堆棧跟蹤相當沒用。

當我評論lint函數時,我的測試實際運行正常,沒有任何問題。
當我在rails控制檯中手動創建工廠並使用.valid?時,它會返回true,所以我不知道lint爲什麼認爲我的工廠無效。

我的用戶廠是這樣的:

FactoryGirl.define do 

    factory :user do 
    ignore do 
     lang { Language.find_by_code('en') || create(:language) } 
    end 

    login "test_user" 
    email "[email protected]" 
    name "Jan" 
    password "test1234" 
    password_confirmation "test1234" 
    role    # belongs_to :role 
    brand    # belongs_to :brand 
    person    # belongs_to :person 
    language { lang } # belongs_to :language 

    factory :admin_user do 
     association :role, factory: :admin 
    end 
    end 
end 

這裏作用語言工廠都非常簡單(只是一些字符串),但品牌廠股份同日而語作爲用戶,因此我使用忽略塊中的代碼,因此FactoryGirl不會在我的數據庫中創建2個'en'語言條目。

任何人都有一些想法,爲什麼我得到這個InvalidFactoryError,也許提供一些見解如何調試呢?


更新1

看來這個問題是由另一家工廠造成的..
我呼籲用戶_ VAR _widget,我鏈接特定的控件與用戶工廠:

factory :user_solar_widget, :class => 'UserWidget' do 
    sequence_number 2 
    user { User.find_by_login('test_user') } # || create(:user) } 
    widget { Widget.find_by_type('SolarWidget') || create(:solar_widget) } 
    end 

如果我取消註釋create(:user)部件,則會爲User工廠獲取InvalidFactoryError。我的猜測是因爲用戶工廠中沒有任何內容說明它有任何user_widgets。我會用回調試驗一下,看看我能否解決這個問題。


更新2

我已經成功加入該到我的用戶廠解決這個問題:

trait :with_widgets do 
    after(:create) do |user| 
    user.user_widgets << create(:user_solar_widget, user: user) 
    end 
end 

凡user_widgets是用戶模型的has_many關聯。通過調用

factory :user_solar_widget, :class => 'UserWidget' do 
    sequence_number 2 
    # removed the user line 
    widget { Widget.find_by_type('SolarWidget') || create(:solar_widget) } 
end 

然後我創建了一個用戶:
後來我改變了我的user_solar_widget廠

create :user, :with_widgets 

不過,這將是很好,如果皮棉功能有點更具體的瞭解無效工廠..

回答

14

FactoryGirl.lint幾乎是無用的,因爲它是不存在的錯誤消息。我建議,而不是包括以下測試:

# Based on https://github.com/thoughtbot/factory_girl/ 
#   wiki/Testing-all-Factories-(with-RSpec) 
require 'rails_helper' 

RSpec.describe FactoryGirl do 
    described_class.factories.map(&:name).each do |factory_name| 
    describe "#{factory_name} factory" do 
     it 'is valid' do 
     factory = described_class.build(factory_name) 
     expect(factory) 
      .to be_valid, -> { factory.errors.full_messages.join("\n") } 
     end 
    end 
    end 
end