Ruby on rails 理解为什么值不是rails回调规范中所期望的值

Ruby on rails 理解为什么值不是rails回调规范中所期望的值,ruby-on-rails,unit-testing,rspec,Ruby On Rails,Unit Testing,Rspec,我正在为购物车应用程序编写单元测试。它包含用户、订单、订单项和产品项。 我编写了以下规范,其中采购项目的总价存储在订单的total属性中:order\u spec.rb describe '#total_price' do before(:each) do user = User.new(email: 'test1@example.com', password: 'test1234') @order = Order.new(user: user) @order

我正在为购物车应用程序编写单元测试。它包含用户、订单、订单项和产品项。 我编写了以下规范,其中采购项目的总价存储在订单的
total
属性中:order\u spec.rb

    describe '#total_price' do
  before(:each) do
    user = User.new(email: 'test1@example.com', password: 'test1234')
    @order = Order.new(user: user)
    @order_item = OrderItem.new(order: @order, unit_price: 100, quantity: 2,
                               total_price: 200)
  end
  it 'calculates order total price' do
    expect(@order.total).to eql(200)
  end
end
订单表包含以下属性: 订单(id、总数、用户id)

但是,在运行规范时,它给出的错误如下:

 1) Order Instance Methods #total_price does something
 Failure/Error: expect(@order.total).to eql(900)

   expected: 900
        got: 0.0

   (compared using eql?)
订单模型与多个订单项目关联,属于一个用户。 订单模型的代码如下所示:

class Order < ApplicationRecord
  belongs_to :user, optional: true
  has_many :order_items
  before_save :update_total

  def total_price
    price = order_items.collect do |order_item|
      order_item.item_unit_price * order_item.quantity
    end
    price.sum
  end

  private

  def update_total
    self[:total] = total_price
  end
end
describe Order, type: :model do
  before(:each) do
    user = User.new(email: 'test1@example.com', password: 'test1234')
    @order = Order.create(user: user)
    p1 = Product.create(name: 'purse', price: 100, stock: 5)
    p2 = Product.create(name: 'shoe', price: 200, stock: 5)
    @order.order_items.create!(product: p1, quantity: 1)
    @order.order_items.create!(product: p2, quantity: 3)
    @order.save!
  end
  describe '#total_price' do
    it 'calculates order total price' do
      expect(@order.total).to eql(700)
    end
  end
end
类顺序
有人能告诉我为什么它不保存总数吗?它存储的是用户,而不是总数。我做错了什么? 我使用rspec和水豚进行测试

请帮忙。
提前感谢。

这里的问题是,您正在体验回调的优点和缺点之一,这是一种间接层次

您可以设置
total
,但在保存模型时会重新计算total。我猜你们有0件商品的单价和/或数量

def total_price
    price = order_items.collect do |order_item|
      order_item.item_unit_price * order_item.quantity
    end
    price.sum
end

因此,要解决这个问题,请更改测试,以确保保存的订单项最终达到您期望的总数

而不是给总数提供一些固定值。创建与规范中的订单相对应的订单项目。然后,编写规范,期望总额等于将根据总价方法中的逻辑计算的值。 不确定order_items表中有哪些字段,但是,代码应该如下所示

describe '#total_price' do
  before(:each) do
    user = User.new(email: 'test1@example.com', password: 'test1234')
    order = Order.new(user: user)
    order_item = OrderItem.new(order: order, item_unit_price: 100, quantity: 2)
end
   it 'calculates order total' do
     expect(order.total_price).to eq(200)
   end
end

因此,经过大量研究,我发现订单项的对象由于验证而无法正确创建。而且我在联想方面也有点困惑。但我现在明白了。正确的rspec如下所示:

class Order < ApplicationRecord
  belongs_to :user, optional: true
  has_many :order_items
  before_save :update_total

  def total_price
    price = order_items.collect do |order_item|
      order_item.item_unit_price * order_item.quantity
    end
    price.sum
  end

  private

  def update_total
    self[:total] = total_price
  end
end
describe Order, type: :model do
  before(:each) do
    user = User.new(email: 'test1@example.com', password: 'test1234')
    @order = Order.create(user: user)
    p1 = Product.create(name: 'purse', price: 100, stock: 5)
    p2 = Product.create(name: 'shoe', price: 200, stock: 5)
    @order.order_items.create!(product: p1, quantity: 1)
    @order.order_items.create!(product: p2, quantity: 3)
    @order.save!
  end
  describe '#total_price' do
    it 'calculates order total price' do
      expect(@order.total).to eql(700)
    end
  end
end

谢谢你

No@austio,这是同样的错误。我已经如上所述更新了rspec,但它仍然是零。我已经更新了问题中的rspec代码,以便您可以查看它。很酷,因此,本文中的数据模型或您收集的数据中对它的引用肯定有问题。我使用的证据是collect返回一个元素数组,数字数组的和产生一个数字。我最好的猜测是,商品的单价返回0.0,这将导致您的金额为0.0,请详细说明?因为我通过控制台进行检查,
order.order\u items
返回该顺序中的所有订单项。那么,返回0的究竟是什么?订单中每个项目的bot
项目\单价
数量
的值是多少?我得到了@Austio的解决方案。我已经添加了解决方案。我尝试了这个,但它给出了相同的错误。请参阅问题中rspec中编辑的代码以供审查。