0

次の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の概念がありません。

4

2 に答える 2

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
于 2012-12-05T13:12:55.010 に答える
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

それが役に立てば幸い。

于 2012-12-04T20:02:14.147 に答える