【问题标题】:RSpec Newbie: "Update attributes => false" not being recognisedRSpec 新手:“更新属性 => false”未被识别
【发布时间】:2011-06-09 05:07:51
【问题描述】:

刚开始使用 RSpec。一切都很顺利,除了一个带有嵌套控制器的规范。

我试图确保当使用无效参数更新“评论”资源(嵌套在“帖子”下)时,它会呈现“编辑”模板。我正在努力让 rspec 识别 :update_attributes => false 触发器。如果有人有任何建议,他们将不胜感激。尝试代码如下:

  def mock_comment(stubs={})
    stubs[:post] = return_post
    stubs[:user] = return_user
    @mock_comment ||= mock_model(Comment, stubs).as_null_object
  end

  describe "with invalid paramters" dog
    it "re-renders the 'edit' template" do
      Comment.stub(:find).with("12") { mock_comment(:update_attributes => false) }
      put :update, :post_id => mock_comment.post.id, :id => "12"
      response.should render_template("edit")
    end
  end

还有控制器:

  def update
    @comment = Comment.find(params[:id])
    respond_to do |format|
      if @comment.update_attributes(params[:comment])
        flash[:notice] = 'Post successfully updated'
        format.html { redirect_to(@comment.post) }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.xml  { render :xml => @comment.errors, :status => :unprocessable_entity }
      end
    end

  end

最后,错误:

 Failure/Error: response.should render_template("edit")
   expecting <"edit"> but rendering with <"">.
   Expected block to return true value.

【问题讨论】:

    标签: ruby-on-rails-3 rspec


    【解决方案1】:

    这是一个非常有趣的问题。一个快速的解决方法是简单地替换 Comment.stub 的块形式:

    Comment.stub(:find).with("12") { mock_comment(:update_attributes => false) }
    

    带有明确的and_return:

    Comment.stub(:find).with("12").\
      and_return(mock_comment(:update_attributes => false))
    

    至于为什么这两种形式会产生不同的结果,这有点让人头疼。如果您使用第一种形式,您会看到当调用存根方法时,模拟实际上返回self 而不是false。这告诉我们它没有对方法进行存根(因为它被指定为空对象)。

    答案是,当传入一个块时,该块只在调用存根方法时执行,而不是在定义存根时执行。所以在使用块形式时,调用如下:

    put :update, :post_id => mock_comment.post.id, :id => "12"
    

    第一次执行mock_comment。因为:update_attributes =&gt; false 没有被传入,所以方法没有被存根,并且返回的是mock 而不是false。当块调用mock_comment 时,它返回@mock_comment,它没有存根。

    相反,使用and_return 的显式形式会立即调用mock_comment。使用实例变量可能会更好,而不是每次都调用方法以使意图更清晰:

    it "re-renders the 'edit' template" do
      mock_comment(:update_attributes => false)
      Comment.stub(:find).with("12") { @mock_comment }
      put :update, :post_id => @mock_comment.post.id, :id => "12"
      response.should render_template("edit")
    end
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-28
      • 2018-10-28
      • 1970-01-01
      • 2017-05-05
      • 2017-01-11
      • 1970-01-01
      • 2012-02-04
      相关资源
      最近更新 更多