0

私は本AgileWebDevelopment with Rails(4th edition)をフォローしていますが、テストケースの失敗で問題が発生しています。

カートに重複アイテムを追加しても、アイテムの数は変わらないが、数量は変わることを確認するテストを作成しました

  test 'adding duplicate products to cart' do
    cart = Cart.new

    ruby_book = products(:ruby)
    cart.add_product ruby_book.id

    assert cart.line_items.length == 1
    assert cart.total_price == ruby_book.price

    p '-------start--------'
    p 'outside add_product'
    p "line_items: #{cart.line_items}"
    cart.add_product ruby_book.id

    assert cart.line_items.length == 1  # TEST FAILS HERE with length == 2
    assert cart.total_price == ruby_book.price * 2 
  end 

基本的にadd_productメソッドをテストします。これは次のとおりです。

class Cart < ActiveRecord::Base
  has_many :line_items, dependent: :destroy

  def add_product(product_id)
    p 'inside add_product'
    p "line_items: #{line_items}"
    p "product_id: #{product_id}"
    current_item = line_items.find_by_product_id(product_id)
    p "current_item: #{current_item}"
    p '---------end---------'
    if current_item
      current_item.quantity += 1
      current_item.price += current_item.product.price
    else
      current_item = line_items.build(product_id: product_id)
      current_item.price = current_item.product.price
    end 
    current_item
  end 

  def total_price
    line_items.to_a.sum { |item| item.price }
  end 
end

テストをデバッグするために、いくつかの印刷呼び出しを追加しました(ご覧のとおり)。出力は次のとおりです。

"-------start--------"
"outside add_product"
"line_items: [#<LineItem id: nil, product_id: 207281424, cart_id: nil, created_at: nil, updated_at: nil, quantity: 1, price: #<BigDecimal:7fa491744fe0,'0.4999E2',18(45)>>]"
"inside add_product"
"line_items: [#<LineItem id: nil, product_id: 207281424, cart_id: nil, created_at: nil, updated_at: nil, quantity: 1, price: #<BigDecimal:7fa491744fe0,'0.4999E2',18(45)>>]"
"product_id: 207281424"
"current_item: "
"---------end---------"

line_itemsアイテムがあることがわかりますproduct_id: 207281424が、何らかの理由で呼び出しline_items.find_by_product_id(product_id)はアイテムを返しませんが、を返しますnil。なんで?

4

3 に答える 3

0

問題はあなたのadd_cart方法にあります。else ブロックでは、line_itemオブジェクトを構築しているだけですが、どこにも保存していません。他のブロックを次のように変更します。

else
  current_item = line_items.build(product_id: product_id)
  current_item.price = current_item.product.price
  current_item.save
end 
于 2012-12-24T13:05:37.913 に答える
0

add_productメソッドは明細項目をデータベースに保存しませんsave。返された項目を呼び出してみてください

...
ruby_book = products(:ruby)
item = cart.add_product ruby_book.id
item.save

assert cart.line_items.length == 1
assert cart.total_price == ruby_book.price


item = cart.add_product ruby_book.id
item.save

assert cart.line_items.length == 1
...
于 2012-12-24T13:07:32.677 に答える
0

ディムクは正しいです。アイテムをカートに保存していません。

current_item = line_items.find_by_product_id(product_id)保存しないと戻っnilてきて、別のビルドを作成することになります。line_itemテストが 1 ではなく 2 を返すようにします。

そして、あなたのtotal_price方法の問題があります。

line_items.to_a.sum { |item| item.price }

あなたのシナリオ(データベースに保存する場合)では、同じ製品を2回追加しているため、1つの品目のみが合計されます。(db に) 保存しないと、各項目が 1 つの数量として機能するため、計算は正しくなります。

数量は項目ごとに定義されるため、数量を計算に適用していることを確認する必要があります。

line_items.to_a.sum { |item| item.price * item.quantity }
于 2012-12-24T17:42:02.517 に答える