2012-11-28 6 views
7

私がクラスCarとMechanicを持っているとします。車には「走る」方法があります。メカニックには何らかの理由でCarが必要です。その後、私はRSpec仕様書を書く。メカニックでは、次のような擬似クラスを定義します。クラス定数を偽るRSpec仕様のベストプラクティスまたは回避策

class Car; end 

以降のメソッドスタブは、メカニックがそのメソッドを使用します。テストを別に実行すると、すべて正常に動作します。しかし、両方のテストを一緒に実行すると(rspec spec/directory /)、私のMechanicスペックは実際のCarクラスを使用します。

So. Rubyのクラスは "オープン"で、カー仕様のためにすでにクラスをロードしているからです。しかし、これを行うよりよい方法はありますか?このような状況のベストプラクティスは何ですか?これは私のコードがおそらく緊密に結合されているためにいくつかの改善が必要なことを意味しますか?

私はgithubのに迅速なデモをした:https://github.com/depy/RspecTest

答えて

2

この偽のクラス文句を言わない作業をRubyのクラスが開かれて以来。

1つの方法として、letを使用してオブジェクトを任意の方法で初期化し、必要に応じて前のブロックで関係を操作します。スタブは前のブロック内でも同様に歓迎されます。 = p

希望すると、これが役立ちます。次のようにコードを考えると、全体

としてテスト:

  • 単位スペック:孤立して各クラスをテスト
  • 統合スペック

+0

しかし、時には私はクラスに何か他のものが含まれているクラスが必要です。私は必要な前に "else"を偽造しなければなりません。そのことについて何? –

+0

これは、私が前のブロックでやったことを言った振る舞いです。 uは2つのクラスを持つことができます.1つはクラスごとに1つ前のブロックでは、最初の呼び出しに基づいて他のオブジェクトを返すスタブを作成できます。 –

2

は、私が何を必要とする二層のテストだと思います:

class Car 
end 

class Mechanic 
    def fix(car) 
    # do something here 
    end 
end 

ユニット仕様の場合、私は依存関係をスタブします。たとえば、

describe Mechanic do 
    let(:mechanic) { described_class.new } 
    let(:car)  { stub(stubbed_method_on_car: 14) } # Or just OpenStruct.new(stubbed_method_on_car: 14) 

    it 'does some stuff' do 
    mechanic.fix(car).should eq true 
    end 
end 

統合の仕様のために私はこれを行うだろう:

describe Mechanic do 
    let(:mechanic) { FactoryGirl.create(:mechanic) } 
    let(:car)  { FactoryGirl.create(:car) } 

    it 'does some stuff' do 
    mechanic.fix(car).should eq true 
    end 
end 
+0

ユニット仕様については、2つの 'let'メソッドのブロックが何をしているのかを記述できますか? – knownasilya

+0

Hm。 Actualの例は、Taskインスタンスによって呼び出されるパブリッシュメソッドを持つNotificationServiceがあることです。 NotificationService.publishの内部では、Notificationオブジェクトが作成され発行されます。タスクがNotificationClviceについて知ることを望まないのは、NotificationServiceを公開用に使用でき、サービスが他のすべての処理を実行できることだけを知っているからです。しかし、どのようにユニットテストを行い、すべてのユニットテストをそれぞれ別々に実行することはできません。私は、通知テストがそれを批判したので、NotificationServiceに実際の通知クラスを使用させたくありません。私はそれが明確になったことを願っています: –

+0

@Knownasilya: 'let'は、すべての例の後で元の状態にリセットされた':mechanic' - > 'mechanic'インスタンス変数へのアクセサを設定します。 –

関連する問題