为什么这个 rspec 在使用 rspec 脚手架的基本"put update"会失败?



为什么 rspec 会在下面列出的基本 rspec put 更新的以下 rspec 消息中说"收到:0 次"?

Failures:
    1) KeywordsController PUT update with valid params updates the requested keyword
Failure/Error: Keyword.any_instance.should_receive(:update_attributes).with({:id => keyword.id, :keyword => {:name => 'keyword name changed'}})
(#<Mocha::ClassMethods::AnyInstance:0x007fc90bfcc7c8>).update_attributes({:id=>853, :keyword=>{:name=>"keyword name changed"}})
    expected: 1 time with arguments: ({:id=>853, :keyword=>{:name=>"keyword name changed"}})
    received: 0 times with arguments: ({:id=>853, :keyword=>{:name=>"keyword name changed"}})
    # ./spec/controllers/keywords_controller_spec.rb:121:in `block (4 levels) in <top (required)>'

keywords_controller_spec.rb

describe KeywordsController do
  describe "PUT update" do
    context "with valid params" do
      it "updates the requested keyword" do
        keyword = create(:keyword)
        Keyword.any_instance.should_receive(:update_attributes).with({:id => keyword.id, :keyword => {:name => 'keyword name changed'}})
        put :update, {:id => keyword.id, :keyword => {:name => 'keyword name changed'}}, valid_session
      end
    end
end

keywords_controller.rb:

class KeywordsController < ApplicationController
  def update
    @keyword = Keyword.find(params[:id])
    respond_to do |format|
      if @keyword.update_attributes(params[:keyword])
        flash[:notice] = t('controllers.keywords.update.success.keyword_updated')
        format.json { render :json => @keyword.to_json, :status => 200 }
        format.xml  { head :ok }
        format.html { redirect_to(edit_keyword_path(@keyword)) }
      else
        format.json { render :text => "Could not update keyword.", :status => :unprocessable_entity }
        format.xml  { render :xml => @keyword.errors, :status => :unprocessable_entity }
        format.html { render :action => :edit, :status => :unprocessable_entity }
      end
    end
  end
end

只是一个猜测,但由于您在创建关键字实例后设置了期望,因此可能没有设置期望。 如果Keyword.find()从缓存中提取该对象,而不是重新创建它,它将失败。

试试这个:

describe KeywordsController do
  describe "PUT update" do
    context "with valid params" do
      it "updates the requested keyword" do
        Keyword.any_instance.should_receive(:update_attributes).with({:id => keyword.id, :keyword => {:name => 'keyword name changed'}})
        keyword = create(:keyword)
        put :update, {:id => keyword.id, :keyword => {:name => 'keyword name changed'}}, valid_session
      end
    end
end

或者,将期望转移到对象本身上(同样,这实际上仅在从缓存中获取时才有意义(:

describe KeywordsController do
  describe "PUT update" do
    context "with valid params" do
      it "updates the requested keyword" do
        keyword = create(:keyword)
        keyword.should_receive(:update_attributes).with({:id => keyword.id, :keyword => {:name => 'keyword name changed'}})
        put :update, {:id => keyword.id, :keyword => {:name => 'keyword name changed'}}, valid_session
      end
    end
end

值得一试!

我遇到了同样的问题。就我而言,使用expect_any_instance_of(Model)而不是Model.any_instance通过测试。我仍然想不通为什么。

希望这有帮助。

describe KeywordsController do
  describe "PUT update" do
    context "with valid params" do
      it "updates the requested keyword" do
        keyword = create(:keyword)
        expect_any_instance_of(Keyword).to receive(:update_attributes).with({:id => keyword.id, :keyword => {:name => 'keyword name changed'}})
        put :update, {:id => keyword.id, :keyword => {:name => 'keyword name changed'}}, valid_session
      end
    end
end

最新更新