40

モデルにメソッドがありました:

class Article < ActiveRecord::Base
  def do_something
  end
end

このメソッドの単体テストもありました。

# spec/models/article_spec.rb
describe "#do_something" do
  @article = FactoryGirl.create(:article)
  it "should work as expected" do
    @article.do_something
    expect(@article).to have_something
  end
  # ...several other examples for different cases
end

after_saveこのメソッドをコールバックに移動する方が良いことがわかるまで、すべて問題ありませんでした。

class Article < ActiveRecord::Base
  after_save :do_something

  def do_something
  end
end

これで、このメソッドに関するすべてのテストが壊れました。次の方法で修正する必要があります。

  • またはこのメソッドもトリガーするdo_somethingため、これ以上特定の呼び出しはありません。そうしないと、db アクションが重複します。createsave
  • createに変更build
  • Respond_to のテスト
  • model.save個々のメソッド呼び出しの代わりに汎用を使用するmodel.do_something

    describe "#do_something" do
      @article = FactoryGirl.build(:article)
      it "should work as expected" do
        expect{@article.save}.not_to raise_error
        expect(@article).to have_something
        expect(@article).to respond_to(:do_something)
      end
    end
    

テストはパスしましたが、私の懸念は、もはや特定のメソッドに関するものではないということです。さらに追加すると、効果は他のコールバックと混合されます。

私の質問は、コールバックになるモデルのインスタンス メソッドを個別にテストする美しい方法はありますか?

4

6 に答える 6

17

shoulda-callback-matchersを使用して、コールバックを呼び出さずにコールバックの存在をテストできます。

describe Article do
  it { is_expected.to callback(:do_something).after(:save) }
end

コールバックの動作もテストしたい場合:

describe Article do
  ...

  describe "#do_something" do
    it "gives the article something" do
      @article.save
      expect(@article).to have_something
    end
  end
end
于 2014-08-28T15:56:45.913 に答える
-1
describe "#do_something" do

 it "gives the article something" do

  @article = FactoryGirl.build(:article)

   expect(@article).to have_something

 @article.save
end

end
于 2015-07-23T08:08:58.397 に答える