40

doubleテストダブルを作成するにはメソッドを使用する必要があるとrspec docに記載されています。しかし、使用しなくても問題なく動作することがわかりますdouble。使わないと何か問題あるのdouble?また、double how MyClassgetsstubやその他の rspec メソッドを使用していない場合はどうなりますか? rspec で実行している場合、それらはすべてのオブジェクトで利用できますか?

require 'spec_helper'

class MyClass

    def self.run
        new.execute
    end

    def execute
        'foo'
    end

end

describe MyClass do

    it 'should stub instance method' do
        obj = MyClass.new
        obj.stub(:execute).and_return('bar')
        obj.execute.should == 'bar'
    end

    it 'should stub class method' do
        MyClass.stub(:run).and_return('baz')
        MyClass.run.should == 'baz'
    end

end
4

2 に答える 2

47

編集:私はあなたの質問を読み直しました、そして私がそれに完全に答えなかったことに気づきました。関連しているので私の元の答えを残しますが、ここにあなたの具体的な答えがあります:

doubleが必要ない理由は、インスタンスメソッドではなくクラスメソッドをスタブしているためです。 doubleクラス自体ではなく、クラスのインスタンスを処理する場合にのみ役立ちます。

もう少し2倍を説明する古い答え:

可能な場合は、テストダブルではなく、常に実際のクラスを使用する必要があります。これにより、より多くのコードが実行され、テストがより包括的になります。テストダブルは、実際のオブジェクトを使用できない、または使用すべきでない状況で使用されます。たとえば、外部リソース(ネットワークやデータベースなど)にアクセスせずにクラスをインスタンス化できない場合、または多数の依存関係があり、それを使用するものをテストするだけの場合は、クラスを作成することをお勧めします。 doubleとdoubleのいくつかのメソッドをスタブします。

より具体的な例を次に示します。テストしているとしましょうMyClass。ただし、インスタンス化するには、 :MyClassを渡す必要があります。FooLogger

mylogger = FooLogger.new
myclass = MyClass.new logger: mylogger

syslogソケットを開き、すぐにスパムを送信し始めるとFooLogger.new、テストを実行するたびにログに記録されます。このテスト中にログをスパムしたくない場合は、代わりにdouble forを作成FooLoggerし、メソッドをスタブアウトすることができます。

mylogger = double(FooLogger)
mylogger.stub(:log)
myclass = MyClass.new logger: mylogger

ほとんどの適切に設計されたクラスは副作用なしにインスタンス化できるため、通常はdoubleの代わりに実際のオブジェクトを使用し、代わりにスタブメソッドを使用できます。クラスに多くの依存関係があり、インスタンス化を困難にするシナリオは他にもあります。doubleは、問題を乗り越えて、本当に気になることをテストする方法です。

私の経験では、doubleを使用する必要があるのはコードの臭いですが、簡単に変更できないクラス(gemなど)を使用する必要があることが多いため、doubleを使用する必要がある場合があります。

于 2013-03-06T16:25:48.873 に答える