1

私はrspecの初心者で、いくつかの問題に直面しています。誰かが私を助けることができますか?

ユーザーの非アクティブ化を担当するコントローラーアクションがあります。rspec テストでカバーしようとしていますが、結果は私が待っているものではありません。

コントローラ:

def deactivate
  @user = User.find(params[:id])
  if !@user.nil?
    @user.update_attribute(:active, false)
    redirect_to users_url
  end
end

コントローラー仕様

describe "PUT #deactivate" do
  describe "with valid parameters" do
    before (:each) do
      @user = mock_model(User, :id => 100, :login => "login", :password => "password123",
                               :email => "email@gmail.com", :active => true)
      User.should_receive(:find).with("100").and_return(@user)
    end

    it "should deactivate an user" do
      @user.stub!(:update_attribute).with(:active, false).and_return(true)
      put :deactivate, :id => "100"
      @user.active.should eq false
    end
  end
end

テスト結果:

1) UsersController PUT #deactivate with valid parameters should deactivate an user
   Failure/Error: @user.active.should eq false

   expected: false
        got: true

   (compared using ==)

したがって、アクティブな属性が false である必要があるのに、なぜ true のままなのかわかりません。何か案は ?

ありがとう!

4

5 に答える 5

1

update_attribute メソッドを不必要にスタブしているようです。その行を削除して、何が起こるかを確認してください。

于 2012-11-12T17:09:35.183 に答える
0

あなたの期待は「間違っています」。

スペックが実行されると何が起こるか見てみましょうit "should deactivate an user":

  1. @user.stub!(:update_attribute).with(:active, false).and_return(true)既存のモック モデルを変更するため、update_attribute引数:activefalse
    1. 戻りますtrue
    2. この呼び出しが発生したことを追跡します(これがモックの機能です)
    3. User(そして、実際のオブジェクトとは異なり、他には何もしません)
  2. put :deactivate, :id => "100"deactivateコントローラーで実数を呼び出します
  3. Controller が を呼び出しますUser.find@userしかし、そのクラス メソッドをモックしました。これは、実際のユーザーを検索する代わりに、モック オブジェクトを返しますid
  4. Controller が を呼び出します@user.update_attribute。しかし、上記のステップ 3 のために、@userここにもモック オブジェクトがあります。そのupdate_attributesメソッドはステップ 1 のものです。上で見たように、true を返し、この呼び出しが発生したことを追跡し、他には何もしません。つまり、の属性は変更されないため、 のままです。@useractivetrue

activeがいつ呼び出されるかを変更するupdate_attributeことは、実際のUserクラスのオブジェクトの機能ですが、仕様の実行中にそのようなオブジェクトは機能しませんでした。この機能は から継承されActiveRecordているため、テストする必要はありません。代わりにupdate_attribute、モック オブジェクトが を受け取ったことをテストします。

    it "should deactivate an user" do
      @user.stub!(:update_attribute).with(:active, false).and_return(true)
      put :deactivate, :id => "100"
      @user.should have_received(:update_attribute).with(:active, false)
    end

(新しい構文でどのように行われshouldたかに基づいて、ここで古い構文について推測しています。)expect

あざけるかどうか?

コントローラーの機能を実際の実装と組み合わせてテストたい場合は、またはそのオブジェクトをモックしないでください。代わりに、 request specを使用してブラウザーの観点からテストします。(コントローラーのみ(モデルがモックされている)およびモデルのみ(他のモデルを除いて、おそらくdoubleは必要ない)の分離テストが必要な場合でも、それを追加することは理にかなっているかもしれません)。UserUser

于 2014-12-23T16:16:52.297 に答える
-1

これを試すことができますか:

describe "should deactivate an user" do
  before do
    @user.stub!(:update_attribute).with(:active, false).and_return(true)
    put :deactivate, :id => "100"
  end
  it { @user.active.should eq false }
end
于 2012-11-12T18:40:26.720 に答える
-2

への呼び出しをモックしている場合update_attribute、モデルはどのように変化しますか?

初心者の場合: スタブとモックを使用しないでください。

最初にテストに関する一般的な知識を得てから、知識をモックとスタブに広げてください。

于 2012-11-12T17:09:49.817 に答える