Ruby on Rails アプリケーションで rSpec を使用してオブザーバーをテストするにはどうすればよいでしょうか?

StackOverflow https://stackoverflow.com/questions/33048

質問

Ruby on Rails アプリケーションの 1 つに ActiveRecord::Observer があるとします。このオブザーバーを rSpec でテストするにはどうすればよいでしょうか?

役に立ちましたか?

解決

あなたは正しい道を進んでいますが、rSpec、オブザーバー、およびモックオブジェクトを使用するときに、イライラする予期しないメッセージエラーが多数発生しました。モデルの仕様をテストするとき、メッセージの期待に基づいてオブザーバーの動作を処理する必要はありません。

あなたの例では、オブザーバーがモデルに対して何を行うかについての知識がなければ、モデルに「set_status」を指定するための本当に良い方法はありません。

したがって、私が好んで使用するのは、 「No Peeping Toms」プラグイン。 上記のコードを考慮し、No Peeping Toms プラグインを使用すると、次のようにモデルを指定します。

describe Person do 
  it "should set status correctly" do 
    @p = Person.new(:status => "foo")
    @p.set_status("bar")
    @p.save
    @p.status.should eql("bar")
  end
end

値を破壊するオブザーバーが存在することを心配することなく、モデル コードを指定できます。次のように person_observer_spec で個別に指定します。

describe PersonObserver do
  it "should clobber the status field" do 
    @p = mock_model(Person, :status => "foo")
    @obs = PersonObserver.instance
    @p.should_receive(:set_status).with("aha!")
    @obs.after_save
  end
end 

本当に本当に結合された Model クラスと Observer クラスをテストしたい場合は、次のように実行できます。

describe Person do 
  it "should register a status change with the person observer turned on" do
    Person.with_observers(:person_observer) do
      lambda { @p = Person.new; @p.save }.should change(@p, :status).to("aha!)
    end
  end
end

99% の場合、オブザーバーをオフにしてスペック テストを行うことをお勧めします。その方が簡単です。

他のヒント

免責事項:実際に運用サイトでこれを行ったことはありませんが、モック オブジェクトを使用するのが合理的な方法のようです。 should_receive と友人、およびオブザーバーのメソッドを直接呼び出します

次のモデルとオブザーバーがあるとします。

class Person < ActiveRecord::Base
  def set_status( new_status )
    # do whatever
  end
end

class PersonObserver < ActiveRecord::Observer
  def after_save(person)
    person.set_status("aha!")
  end
end

私なら次のような仕様を書きます (実行してみたら成功しました)

describe PersonObserver do
  before :each do
    @person = stub_model(Person)
    @observer = PersonObserver.instance
  end

  it "should invoke after_save on the observed object" do
    @person.should_receive(:set_status).with("aha!")
    @observer.after_save(@person)
  end
end

no_peeping_toms は現在 gem であり、ここで見つけることができます。 https://github.com/patmaddox/no-peeping-toms

オブザーバーが正しいモデルを観察し、期待どおりに通知を受信することをテストする場合は、RR を使用する例を次に示します。

your_model.rb:

class YourModel < ActiveRecord::Base
    ...
end

your_model_observer.rb:

class YourModelObserver < ActiveRecord::Observer
    def after_create
        ...
    end

    def custom_notification
        ...
    end
end

your_model_observer_spec.rb:

before do
    @observer = YourModelObserver.instance
    @model = YourModel.new
end

it "acts on the after_create notification"
    mock(@observer).after_create(@model)
    @model.save!
end

it "acts on the custom notification"
    mock(@observer).custom_notification(@model)
    @model.send(:notify, :custom_notification)
end
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top