0

私は次のように失敗するrspecシナリオを書いています:

 (#<User:0x1056904f0>).update_attributes(#<RSpec::Mocks::ArgumentMatchers::AnyArgMatcher:0x105623648>)
     expected: 1 time
     received: 0 times

users_controller_spec.rb:

describe "Authenticated examples" do
  before(:each) do
    activate_authlogic
    @user = Factory.create(:valid_user)
    UserSession.create(@user)
  end

describe "PUT update" do
    it "updates the requested user" do
      User.stub!(:current_user).and_return(@user)
      @user.should_receive(:update_attributes).with(anything()).and_return(true)
      put :update, :id => @user , :current_user => {'email' => 'Trippy'}
      puts "Spec Object Id : " + "#{@user.object_id}"
 end

users_controller.rb:

def update
  @user = current_user
  puts "Controller Object ID is : " + "#{@user.object_id}"

  respond_to do |format|
    if @user.update_attributes(params[:user])
      format.html { redirect_to(root_url, :notice => 'Successfully updated profile.') }
      format.xml  { head :ok }
    else
      format.html { render :action => "edit" }
      format.xml  { render :xml => @user.errors, :status => :unprocessable_entity }
    end
  end
end

user.rb-ファクトリ

Factory.define :valid_user, :class => User do |u|
  u.username "Trippy"
  u.password "password"
  u.password_confirmation "password"
  u.email "elephant@gmail.com"
  u.single_access_token "k3cFzLIQnZ4MHRmJvJzg"
  u.id "37"
end
4

2 に答える 2

2

スタブとメッセージの期待を混同していると思います。この線

User.should_receive(:find)

User モデルが検索メッセージを受信することを期待するよう Rspec に指示します。一方:

User.stub!(:find)

テストに合格できるように find メソッドを置き換えます。あなたの例では、テストしているのupdate_attributesは正常に呼び出されたかどうかです。そのため、メッセージの期待がどこに行くべきか、他のすべてのテスト コードの仕事は前提条件を設定することだけです。

その行を次のように置き換えてみてください。

User.stub!(:find).and_return(@user)

findIDだけでなく、オブジェクトを返すことに注意してください。findまた、ここでスタブアウトすることは、処理を高速化するためだけに役立つことに注意してください。書かれているように、例はshould_receive(:find)正常に処理さます。これは、ファクトリを使用してテスト データベースにユーザーを作成しているためです。スタブを取り出してもテストは引き続き機能するはずですが、データベースにヒットするという犠牲が伴います。

もう 1 つのヒント: コントローラーのテストが機能しない理由を理解しようとしている場合、beforeフィルターによってブロックされているかどうかを知ることが役立つ場合があります。これは次の方法で確認できます。

controller.should_receive(:update)

それが失敗した場合update、おそらくbeforeフィルターが要求をリダイレクトしたため、アクションに到達していません。

于 2010-09-09T18:43:15.077 に答える
2

などの Authlogic の標準ヘルパー メソッドは、直接current_user呼び出さないでください。User.find私はそれがcurrent_user_session.userどこにあると信じているので、あなたは直接current_user_session電話していません。そこで派手なチェーン スタブを行うこともできますが、私の提案は、現在スタブしているものの代わりに、これをコントローラーの仕様に追加することです。UserSession.findUser.find

stub!(:current_user).and_return(@user)

RSpec2では、あなたがしなければならないかもしれません

controller.stub!(:current_user).and_return(@user)

編集:これは仕様ファイル全体である必要があります:

describe "Authenticated examples" do
  before(:each) do
    activate_authlogic
    @user = Factory.create(:valid_user)
    UserSession.create(@user)
  end

describe "PUT update" do

  describe "with valid params" do
    it "updates the requested user" do
      stub!(:current_user).and_return(@user)
      @user.should_receive(:update_attributes).with(anything()).and_return(true)
      put :update, :id => @user , :current_user => {'email' => 'Trippy'}
    end
 end
于 2010-09-09T21:07:03.883 に答える