将参数传递给post:createrequestruby-on-rails-3.1,Rspec,factorygirl

将参数传递给post:createrequestruby-on-rails-3.1,Rspec,factorygirl,ruby-on-rails-3.1,rspec2,factory-bot,Ruby On Rails 3.1,Rspec2,Factory Bot,我正在尝试编写一个控制器规范,用于创建带有采购行项目的采购。采购创建得很好,具有我赋予它的所有属性,但未创建采购行项目。这是我的密码: 工厂。rb PurchaseLineItem.rb Purchase.rb 采购控制员 采购控制器规格 require 'spec_helper' describe PurchasesController do login_user describe "POST create" do before(:each) do @abil

我正在尝试编写一个控制器规范,用于创建带有采购行项目的采购。采购创建得很好,具有我赋予它的所有属性,但未创建采购行项目。这是我的密码:

工厂。rb

PurchaseLineItem.rb

Purchase.rb

采购控制员

采购控制器规格

require 'spec_helper'

describe PurchasesController do

  login_user

  describe "POST create" do
    before(:each) do
      @ability.can :create, Purchase
    end

    it "should pass the params to purchase" do
      purchase = Factory(:purchase)
      post :create, purchase: purchase.attributes.except("id")
      assigns(:purchase).po_number.should == purchase.po_number     
    end

    it "should pass the params to purchase_line_items" do
      purchase = Factory(:purchase)   
      post :create,   purchase: purchase.attributes, purchase_line_items_attributes: purchase.purchase_line_items.first.attributes 
      assigns(:purchase).purchase_line_items.first.unit_price.should == purchase.unit_price
    end
  end
end

提前谢谢

把它弄明白了。我改变了一些东西,但问题是语法。在PurchasesController规范中,我将代码更改为:

describe PurchasesController do
  login_user
  render_views

  before(:each) do
    @purchase = Factory(:purchase)
  end

  describe "POST create" do
    before(:each) do
      @ability.can :create, Purchase
    end

    it "should pass the params to purchase" do
      i = @purchase.id
      p = @purchase.attributes.except('id', 'created_at', 'updated_at')
      pl = @purchase.purchase_line_items.first.attributes.except('id', 'purchase_id', 'created_at', 'updated_at')
      post :create, purchase: { attributes: p, purchase_line_items_attributes: [pl] }
      assigns(:purchase).attributes.except('id', 'created_at', 'updated_at').should == p
      assigns(:purchase).purchase_line_items.first.attributes.except('id', 'purchase_id', 'created_at', 'updated_at').should == pl
    end
  end
end
需要从以下位置更改语法:

post :create, purchase: purchase.attributes, purchase_line_items_attributes: purchase.purchase_line_items.first.attributes
致:


现在一切都好了

在Rails 4下,这种通用性对我来说并不适用:

post :create, purchase: { attributes: p, purchase_line_items_attributes: [pl] } 
下面是我发现的一种通用样式,它可以满足本文的要求:create…updated for Rails 4。注意:有效的_会话可能无法完全像我正在存根一样工作,但您得到了枯燥的想法;)

在Rails 4中,如果将控制器设置为使用:

params.require(:purchase).permit(...)

并从模型中删除可访问的属性,这样您就不必担心使用属性。除了(…)进行过滤。

感谢您的更新!我发布的规范有点像是一个虚拟规范,我想知道如何将参数传递给实际测试。您的答案绝对是测试控制器的更好方法。@eric wanchic谢谢!您的
valid_session
模式对于测试具有cancan权限的Rails 4控制器是一个非常有用且优雅的解决方案。这很有效。我们还可以通过执行
parameters=ActionController::parameters.new
手动创建参数,然后执行API中包含的所有操作。我们必须
。要求(:购买)。许可并将参数作为两个单独的对象传递,例如
def purchase_params.require(:purchase)。permit(…)end
,然后传递其他参数。
describe PurchasesController do
  login_user
  render_views

  before(:each) do
    @purchase = Factory(:purchase)
  end

  describe "POST create" do
    before(:each) do
      @ability.can :create, Purchase
    end

    it "should pass the params to purchase" do
      i = @purchase.id
      p = @purchase.attributes.except('id', 'created_at', 'updated_at')
      pl = @purchase.purchase_line_items.first.attributes.except('id', 'purchase_id', 'created_at', 'updated_at')
      post :create, purchase: { attributes: p, purchase_line_items_attributes: [pl] }
      assigns(:purchase).attributes.except('id', 'created_at', 'updated_at').should == p
      assigns(:purchase).purchase_line_items.first.attributes.except('id', 'purchase_id', 'created_at', 'updated_at').should == pl
    end
  end
end
post :create, purchase: purchase.attributes, purchase_line_items_attributes: purchase.purchase_line_items.first.attributes
post :create, purchase: { attributes: p, purchase_line_items_attributes: [pl] }   
post :create, purchase: { attributes: p, purchase_line_items_attributes: [pl] } 
describe PurchasesController do
  def valid_session
    controller.stub!(:authorize).and_return(User)
  end

  describe 'POST :create' do
    before do
      purchase = FactoryGirl.build(:purchase).attributes
      purchase_line_item = { purchase_line_items_attributes: { "#{rand(903814893)}" =>  FactoryGirl.build(:purchase_line_item).attributes } }
      @valid_attributes = purchase.merge(purchase_line_item)
    end

    context "with valid params" do
      before(:each) do
        post :create, { purchase: @valid_attributes }, valid_session
      end

      it "assigns a newly created purchase as @purchase" do
        assigns(:purchase).should be_a(Purchase)
      end

      it "saves a newly created purchase" do
        assigns(:purchase).should be_persisted
      end

      it "redirects to the created purchase" do
        response.should redirect_to(Purchase.last)
      end

    end

    context "with invalid params" do
      before do
        Purchase.any_instance.stub(:save).and_return(false)
        post :create, { purchase: @valid_attributes }, valid_session
      end

      it "assigns a newly created but unsaved purchase as @purchase" do
        assigns(:purchase).should be_a_new(Purchase)
      end

      it "re-renders the :new template" do
        response.should render_template("new")
      end

      it "returns http success" do
        response.should be_success
      end

    end

  end


end
params.require(:purchase).permit(...)