如何将params参数传递给rspec控制器测试?

时间:2012-12-04 19:58:21

标签: ruby-on-rails-3 rspec ruby-on-rails-3.2 params

我有以下rspec测试:

def valid_attributes
  { "product_id" => "1" }
end

describe "POST create" do
  describe "with valid params" do
    it "creates a new LineItem" do
      expect {
        post :create, {:line_item => valid_attributes}, valid_session #my valid_session is blank
      }.to change(LineItem, :count).by(1)
    end

哪个失败并出现此错误:

1) LineItemsController POST create with valid params redirects to the created line_item
   Failure/Error: post :create, {:line_item => valid_attributes}, valid_session
   ActiveRecord::RecordNotFound:
     Couldn't find Product without an ID
     # ./app/controllers/line_items_controller.rb:44:in `create'
     # ./spec/controllers/line_items_controller_spec.rb:87:in `block (4 levels) in <top (required)>'

这是我的控制器的创建动作:

def create
  @cart = current_cart
  product = Product.find(params[:product_id])
  @line_item = @cart.line_items.build(:product => product)

  respond_to do |format|
    if @line_item.save
      format.html { redirect_to @line_item.cart, notice: 'Line item was successfully created.' }
      format.json { render json: @line_item.cart, status: :created, location: @line_item }
    else
      format.html { render action: "new" }
      format.json { render json: @line_item.errors, status: :unprocessable_entity }
    end
  end
end

如您所见,我的操作需要来自请求的params对象的product_id。 我应该如何将此product_id用于我的rspec测试?

我尝试过这个before声明:

before(:each) do
    ApplicationController.any_instance.stub(:product).and_return(@product = mock('product'))
  end

。 。 。但它什么都没改变。我在某处遗漏了一些rspec概念。

2 个答案:

答案 0 :(得分:0)

试试这样:

describe "POST create" do
   describe "with valid params" do
      it "creates a new LineItem" do
         expect {
            post :create, :product_id => 1
         }.to change(LineItem, :count).by(1)
      end

希望它有所帮助。

答案 1 :(得分:0)

我最后通过使用灯具解决了我的问题,而不是试图按照另一个答案的建议来模拟解决方案。

原因是控制器执行查询以从数据库获取信息:product = Product.find(params[:product_id])我发现基于夹具的解决方案比使用模拟的解决方案更快解决我的问题而我无法想象如何快速存根查询(灯具也有助于控制器上的另一个测试,所以它最终帮助。

供参考:

我在测试的顶部引用了我的夹具:fixtures :products

我将测试改为:

describe "POST create" do
  describe "with valid params" do
    it "creates a new LineItem" do
      expect {
          post :create, :product_id => products(:one).id
       }.to change(LineItem, :count).by(1)
    end

这是我的夹具文件,products.yml:

one:
    name: FirstProduct
    price: 1.23

two:
    name: SecondProduct
    price: 4.56