2016-07-29 7 views
0

私はRuby 2.2.1とRails 4.2.0を使用していますオブジェクトを再利用するRspecテスト

モジュールをカバーするためにテストケースを追加します。モジュールは、基本的に、別のシステムから取り込まれたデータに対していくつかのQAチェックを実行します。私が抱えている問題は、テストケース全体で、モジュール内の反復が個々のテストケースのために個々のオブジェクトの代わりに同じオブジェクトを再使用していることです。

サンプルテストケース:

... 

it "should add issue case 1" do 
    trip = FactoryGirl.build(:trip, :case_1) 
    p trip.object_id # 7...8660 
    subject.do_qa(trip) 
    expect(trip.issue_1).not_to be_nil 
end 

it "should add issue case 2" do 
    trip = FactoryGirl.build(:trip, :case_2) 
    p trip.object_id # 7...2780 
    subject.do_qa(trip) 
    expect(trip.issue_2).not_to be_nil 
end 

... 

サンプルモジュール:

module Qa 

    ... 

    def self.do_qa(trips) 
    p trips.object_id # Same is the object id in the calling test case 
    @trips ||= Array.wrap(trips) 
    @trips.each do |t| 
     p t.object_id # Always the object id from the first test case! 
     ... # Checks for case 1 and case 2 
    end 
    end 

    ... 

end 

モジュールは単に再評価されているため、ループがオブジェクトを再使用して、第二のテストケースを通過したことがないので最初のtripオブジェクトです。ループ内に新しいオブジェクトをインスタンス化するよう強制する方法はありますか?

+0

ひどいやり方がありますが、より良い方法があるかもしれませんが、もっとコードを見る必要があります。 'Qa'の他の方法は' @trips'を参照していますか?どのクラスに 'Qa'が含まれていますか?あなたのテストでは 'subject 'とは何ですか? ([RSpecの主題は主に悪いことです。](http://stackoverflow.com/questions/38437162/whats-the-difference-between-rspecs-subject-and-let-when-should-theybebeused) ) –

答えて

0

これに対する答えは、Rubyと他の言語の完全な理解が不足していました。基本的には、モジュールがクラスとして定義されていなくても、それはまだ舞台裏のクラスであり、インスタンス変数は実行の間に設定されたままです。これは私のアプリケーションでは問題ではありません。なぜなら、メソッド呼び出しの間にそれらがクリアされていることに何も依存していないからです。インスタンス変数は、私が||=演算子を使用していたので、まだ元tripのオブジェクトが含まれているために起こっているのコースのように、元の質問で

ケース1とケース2は、実際には、Qaクラスの同じインスタンスを使用しています。

before(:each)ブロックをQa.instance_variable_set(:@trips, [])という関連コンテキストの先頭に追加して、変数がクリーンな状態で確実に開始されるようにして解決しました。

+0

ええ、または適切なOOPを実行して、グローバル状態でデータを保存することはできません。意味は、実際には 'Qa'クラスをインスタンス化し、__class__ではなく__instance__で動作します。 –

関連する問題