2016-04-14 11 views
0

パブリケーションテーブルに自己結合がある記事翻訳を作成するためのシステムをテストしようとしています。私は複数の翻訳を作成し、それらを「親」の記事に関連付けるファクトリを作成しました。工場ガール自己結合検証エラーを投げる

# models/publication.rb 

    has_many :translations, class_name: "Publication", foreign_key: "translation_id", dependent: :nullify 
    belongs_to :translation, class_name: "Publication", optional: true 

    validates :language, uniqueness: { scope: :translation_id }, if: :is_translation? 

    def is_translation? 
    !translation.nil? 
    end 
:factory_girl 4.7.0、RSpecの、そしてDatabase_cleaner

すべてのアクションが期待通りに動作しますが、テストを作成しても問題ここ

あるとRailsの5を使用して

は、関連するモデルの検証とメソッドをです

ファクトリー(無関係なコードは省略):

# spec/factories/publication.rb 
    factory :publication, aliases: [:published_pub] do 
    title 'Default Title' 
    language 'EN' 
    published 

    after(:build) do |object| 
     create(:version, publication: object) 
    end 

    #-- This is where I suspect the problem stems from 

    trait :with_translations do 
     association :user, factory: :random_user 

     after(:build) do |object| 
     create_list(:translation, 3, {user: object.user, translation:object}) 
     end 
    end 
    end 

    factory :translation, class: Publication do 
    sequence(:title) { |n| ['French Article', 'Spanish Article', 'German Article', 'Chinese Article'][n]} 
    sequence(:language) { |n| ['FR', 'ES', 'DE', 'CN'][n]} 
    user 
    end 

そして、基本的なテスト:

# spec/models/publication_spec.rb 
    before(:each) do 
     @translation_parent = create(:publication, :with_translations) 
     @pub_without_trans = create(:publication, :with_random_user) 
    end 

    scenario 'is_translation?' do 
     # No actual test code needed, this passes regardless 
    end 

    scenario 'has_translations?' do 
     # No actual test code needed, this (and subsequent tests) fail regardless 
    end 

最後に、エラー:

Failure/Error: create_list(:translation, 3, {user: object.user, translation:object}) 

ActiveRecord::RecordInvalid: 
    Validation failed: Language has already been taken 

は、最初のテストは合格(と翻訳と出版オブジェクトが正しく作成されている)が、任意の後続のテストが失敗します。問題は、translation_idにスコープされた一意性検証があり、factorygirlが、完全に新しいパブリケーションを作成するのではなく、既存のパブリケーションに生成されたトランスレーションを追加しようとしているようです。

ご協力いただきましてありがとうございます。

答えて

0

解決済み!

translation工場のシーケンスイテレータが各テスト後に0にリセットされないという問題がありました。そのため、テスト1の後、存在しなかった配列インデックスにアクセスしようとしました。それがもう一度やって来ると、バリデーションが始まり、テストは失敗しました!

ソリューションはかわいいではありませんが、当分の間は十分だ

sequence(:language) do |iteration| 
    array = ['FR', 'ES', 'DE', 'CN'] 
    # Returns a number between 0 and array.length 
    array[iteration%array.length] 
end 
sequence(:title) do |iteration| 
    array = ['French Article', 'Spanish Article', 'German Article', 'Chinese Article'] 
    # Returns a number between 0 and array.length 
    array[iteration%array.length] 
end