0

以下のコード サンプルは、RSpec Book のコントローラー仕様に関する章からのリファクタリングを示しています。

require 'spec_helper'

describe MessagesController do
  describe "POST create" do
    it "creates a new message" do
      message = mock_model(Message).as_null_object
      Message.should_receive(:new).
        with("text" => "a quick brown fox").
        and_return(message)
      post :create, :message => { "text" => "a quick brown fox" }
    end

    it "saves the message" do
      message = mock_model(Message)
      Message.stub(:new).and_return(message)
      message.should_receive(:save)
      post :create
    end

    it "redirects to the Messages index" do
      post :create
      response.should redirect_to(:action => "index")
    end
  end
end

require 'spec_helper'

describe MessagesController do
  describe "POST create" do
    let(:message) { mock_model(Message).as_null_object }

    before do
      Message.stub(:new).and_return(message)
    end

    it "creates a new message" do
      Message.should_receive(:new).
        with("text" => "a quick brown fox").
        and_return(message)
      post :create, :message => { "text" => "a quick brown fox" }
    end

    it "saves the message" do
      message.should_receive(:save)
      post :create
    end

    it "redirects to the Messages index" do
      post :create
      response.should redirect_to(:action => "index")
    end
  end
end

いくつか質問があります。

1) 作成と保存の両方のテストが mock_model を使用するため、let ブロックを使用する利点を理解しています。しかし、before ブロックの利点がわかりません。保存テストのみがスタブを必要とする場合、各テストの前に実行される before ブロックにコードを移動するのではなく、コードをテスト内に保持しないのはなぜですか?

2) より基本的には、before ブロックは作成テストが指定しているものに干渉しますか? 作成テストは、Message がいくつかのパラメーターで new を受け取る必要があることを示し、post :create でそれをテストします。しかし、before ブロックが単に new への呼び出しをスタブ化するだけの場合、作成テストで should_receive アサーションをショートさせませんか? おそらく、stub と should_receive がどのように相互作用するかを理解していません。

4

1 に答える 1

0

保存テストだけがスタブを必要とする場合

典型的な作成アクションは次のようになります。

def create
  @message = Message.new(params[:message])
  if @message.save
    # ... etc. ...

はい、Message.new例ごとにスタブ化する必要があります。

before ブロックが単に new への呼び出しをスタブ化するだけの場合、作成テストで should_receive アサーションをショートさせませんか?

実際には、逆に機能します。before ブロックが最初に実行され:new、スタブが出力されます。次に、メッセージの期待値が実行され、スタブが置き換えられます。beforeブロックを削除して、他の 2 つの例の先頭にスタブを配置しても、同じ効果が得られます。

于 2012-11-06T04:22:55.057 に答える