【问题标题】:RSpec, stubbing nested resource methodsRSpec,存根嵌套资源方法
【发布时间】:2010-03-31 15:22:43
【问题描述】:

我有两个模型:

class Solution < ActiveRecord::Base
  belongs_to :owner, :class_name => "User", :foreign_key => :user_id
end

class User < ActiveRecord::Base
  has_many :solutions
end

我将解决方案嵌套在这样的用户中:

ActionController::Routing::Routes.draw do |map|
  map.resources :users, :has_many => :solutions
end

最后是我要指定的操作:

class SolutionsController < ApplicationController
  before_filter :load_user

  def show
    if(@user)
      @solution = @user.solutions.find(params[:id])
    else
      @solution = Solution.find(params[:id])
    end
  end

  private

  def load_user
    @user = User.find(params[:user_id]) unless params[:user_id].nil?
  end
end

我的问题是,我到底是如何指定 @user.solutions.find(params[:id]) 的?

这是我目前的规格:

describe SolutionsController do

  before(:each) do
    @user = Factory.create(:user)
    @solution = Factory.create(:solution)
  end

  describe "GET Show," do

    before(:each) do
      Solution.stub!(:find).with(@solution.id.to_s).and_return(@solution)
      User.stub!(:find).with(@user.id.to_s).and_return(@user)
    end

    context "when looking at a solution through a user's profile" do

      it "should find the specified solution" do
        Solution.should_receive(:find).with(@solution.id.to_s).and_return(@solution)
        get :show, :user_id => @user.id, :id => @solution.id
      end
    end
  end

但这给我带来了以下错误:

1)Spec::Mocks::MockExpectationError in 'SolutionsController GET Show, when looking at a solution through a user's profile should find the specified solution'
<Solution(id: integer, title: string, created_at: datetime, updated_at: datetime, software_file_name: string, software_content_type: string, software_file_size: string, language: string, price: string, software_updated_at: datetime, description: text, user_id: integer) (class)> received :find with unexpected arguments 
  expected: ("6")
  got: ("6", {:group=>nil, :having=>nil, :limit=>nil, :offset=>nil, :joins=>nil, :include=>nil, :select=>nil, :readonly=>nil, :conditions=>"\"solutions\".user_id = 34"})

谁能帮我解决我如何存根@user.solutions.new(params[:id])

【问题讨论】:

    标签: ruby-on-rails unit-testing rspec bdd nested-resources


    【解决方案1】:

    看起来我找到了自己的答案,但我将把它贴在这里,因为我似乎无法在网上找到很多关于此的内容。

    RSpec 有一个名为 stub_chain 的方法:http://apidock.com/rspec/Spec/Mocks/Methods/stub_chain

    这样可以很容易地存根类似的方法:

    @solution = @user.solutions.find(params[:id])
    

    通过这样做:

    @user.stub_chain(:solutions, :find).with(@solution.id.to_s).and_return(@solution)
    

    那么我可以像这样编写一个 RSpec 测试:

    it "should find the specified solution" do
      @user.solutions.should_receive(:find).with(@solution.id.to_s).and_return(@solution)
      get :show, :user_id => @user.id, :id => @solution.id
    end
    

    我的规范通过了。但是,我仍然在这里学习,所以如果有人认为我在这里的解决方案不好,请随时发表评论,我会尝试完全正确。

    【讨论】:

    【解决方案2】:

    使用新的 RSpec 语法,您可以像这样对链进行存根

    allow(@user).to receive_message_chain(:solutions, :find)
    # or
    allow_any_instance_of(User).to receive_message_chain(:solutions, :find)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多