2016-05-31 3 views
1

私はRSpecのActiveRecordモデルをテストしていますが、FactoryGirlモデルを作成する代わりに、モデルをインスタンス化するだけでテストをスピードアップしようとしていますが、falseがあるとがtrueを返しています。Rails .include?

私はテストが...場所モデルのインスタンスの引数を渡されたスケジュールモデル、この方法で

def available_at_location(location) 
    locations.include?(location) 
end 

、テストが...

ですよコード
before do 
    subject.locations = [location_b] 
end 

it 'returns false' do 
    result = subject.available_at_location(location_a) 

    expect(result).to be(false) 
end 

私はFactoryGirlテストパスとinclude?リターンfalselocation_alocation_bを作成するが、私はこのコードでlocation_alocation_bをインスタンス化する場合、テストは失敗し、税込うーん? trueを返します。

let(:location_a) { Location.new(name: 'London') } 
let(:location_b) { Location.new(name: 'York') } 

印刷locationsは、location_bを含むCollectionProxyであることを示し、そしてlocation引数を印刷することは、正しい特性を有するlocation_a、両方であることを示しています。そして、include?は、location引数が受け渡されるかどうかを返します。trueを返します。

EDIT:いくつかの追加コード。 ...

この

は対象を定義するためのコード...

subject { described_class.new(locations: [location_a]) } 

であり、これがfactorygirl場所工場のためのコードである

require 'faker' 

FactoryGirl.define do 
    factory :location do 
    name { Faker::Company.name } 
    address { Faker::Address.street_address } 
    city { Faker::Address.city } 
    zipcode { Faker::Address.zip_code } 
    landline { Faker::PhoneNumber.phone_number } 
    association :organization 
    end 
end 

N.B.私はコンストラクタ(Location.new(name: 'London', organization: Organization.new))に組織を提供しようとしましたが、出力を変更しません。 include?戻りtrue - 両方のレコードが新規であり、id == nilを持っているので

+0

お買いものに役立つ情報交換ができます。 – Ilya

+0

私はあなたが被写体の定義を意味するかどうかはわかりませんでした(私はいつでも被写体を作成するためにFGを使用していませんでした)か、場所のFactoryGirlですが、私は両方を投稿の編集に提供しました。 – Squig

答えて

1

私は解決策を働いてきました。他の誰かが似たような問題を抱えている場合は、ここでこれを文書化します。これらの行は

subject { described_class.new(locations: [location_a]) } 

before do 
    subject.locations = [location_b] 
end 

FactoryGirlによって作られたモデルのインスタンスの代わりに、本格的なDBモデルを使用して、ActiveRecordのはCollectionProxies内の項目への変更を更新しません...問題です。あなたが[location_b]に項目を変更しても、locationsについては、常に[location_a]となります。

解決策は、プロパティを1回だけ割り当てることです。私。

subject { described_class.new(locations: []) } 

before do 
    subject.locations = [location_b] 
end 

各コンテキストのbeforeブロックの位置を必要な場所に設定します。

私は、これはコレクション/ CollectionProxyへの参照とは何かであると確信しているが、それは私を超えます。

4

CollectionProxyは、彼らのid秒でモデルを比較します。あなたのテストは、あなたがデシベルにモデルを保存する必要が働いていると

create!などを使用)

+0

私はLocationコンストラクタで 'id'を提供しようとしましたが、それは助けになりませんでした。モデルがDBに保存されている場合にのみ機能しますか? – Squig

+2

インスタンス化されているが保存されていないオブジェクトのみを使用するARモデルテストを書くのは難しいことです。かなり頻繁に、あなたが期待していなかった保存されたオブジェクト(ID付き)が必要な状況に遭遇します。モデルからメソッドを抽出し、それらを他のクラスに配置して、DBとやりとりすることなくテストできます。 – zetetic

+0

これはいい考えです、ありがとうございます。 – Squig