【问题标题】:Agile Web Development with Rails 4 - Iteration E3 Unit Tests使用 Rails 4 进行敏捷 Web 开发 - 迭代 E3 单元测试
【发布时间】:2016-01-15 13:25:11
【问题描述】:

我是 Ruby on Rails 的新手,正在阅读“使用 Rails 4 进行敏捷 Web 开发”一书。在第 10 章(迭代 E3 - 完成购物车)末尾做“游戏时间”练习时,我偶然发现了一些问题。

其中之一是在第二个练习中,其中应该创建单元测试以将独特和重复的产品添加到某些购物车中。 当一个人将产品添加到该购物车时,它可能是该类型的第一个产品,因此数量是一个,但每个额外的添加操作都会增加数量。这在浏览器测试中运行良好,但我的测试用例失败了。

测试用例:

test 'duplicates must not be saved as a new line item' do
  # create cart and add one product
  cart = new_cart_with_one_product(:ruby)
  assert cart.save
  assert_equal 1, cart.line_items.count
  assert_equal 1, cart.line_items.find_by(
                   product_id: products(:ruby).id).quantity
  assert_equal 49.50, cart.total_price.to_f
  # ----------------------------------------------------------------


  # create a second (actually the same product) and add it to cart:
  item = products(:ruby)
  cart.add_product(item.id, item.price)
  assert cart.save
  assert_equal 1, cart.line_items.count, 'duplicate saved as new line'

  # test FAILS at the next two lines:
  assert_equal 2, cart.line_items.find_by(product_id: item.id).quantity,
             'quantity has not been increased'
  assert_equal 99.00, cart.total_price.to_f, 'total price is wrong'
end

它告诉我期望值为 2,但实际值为 1。 所以数量没有增加。总价格也没有变化,尽管两者都在开发环境中起作用。

这是 Cart-Model 的代码:

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

  def add_product(product_id, product_price)
    current_item = line_items.find_by(product_id: product_id)

    if current_item
      current_item.quantity +=1
    else
      # create a new line_item
      current_item = line_items.build(product_id: product_id,
                                   price: product_price)
    end

    current_item
  end

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

我在 Ruby 2.2.3 上使用 Rails 4.2.5。 我希望有人可以帮助我,因为我不明白为什么会在测试环境中发生这种情况并且只使用rake test。如果您需要任何其他代码,请告诉我。

【问题讨论】:

  • 在使用cart.reload 保存后尝试reloading cart 对象。您可以将失败的测试行更改为 assert_equal 2, cart.reload.line_items.find_by... stackoverflow.com/questions/5519741/… 有关于需要 reload 的解释。
  • 感谢@PrakashMurthy,但不幸的是这并没有帮助。我之前试过cart.line_items(true),它绕过了缓存,但这也无济于事(即使结合你的建议)。

标签: ruby-on-rails unit-testing


【解决方案1】:

我终于发现了我的错误:

数量肯定会在模型中增加,但不会保存在那里。 它保存在控制器中,因此在我的测试中完全绕过了这一步,因为它只是测试模型本身。

为了修复测试,我将 cart.add_product(item.id, item.price) 更改为 cart.add_product(item.id, item.price).save 以修复该问题。

我还在测试前重新加载了购物车,否则它会计算旧的总价格(感谢@PrakashMurthy,虽然它应该解决另一个问题,但最终它有所帮助:-))。

(工作的)测试用例现在看起来像这样:

test 'duplicates must not be saved as a new line item' do
  # create cart and add one product
  cart = new_cart_with_one_product(:ruby)
  assert cart.save
  assert_equal 1, cart.line_items.count
  assert_equal 1, cart.line_items.find_by(
               product_id: products(:ruby).id).quantity
  assert_equal 49.50, cart.total_price.to_f
  # ----------------------------------------------------------------


  # create a second (actually the same product) and add it to cart:
  item = products(:ruby)

  # the following two lines do the trick:
  cart.add_product(item.id, item.price).save
  cart.reload

  assert cart.save
  assert_equal 1, cart.line_items.count, 'duplicate saved as new line'
  assert_equal 2, cart.line_items.find_by(product_id: item.id).quantity,
         'quantity has not been increased'
  assert_equal 99.00, cart.total_price.to_f, 'total price is wrong'
end

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多