Понимание, почему значение не то, что ожидается в спецификации обратных вызовов rails - PullRequest
0 голосов
/ 17 ноября 2018

Я пишу юнит-тесты для приложения shopping_cart. Содержит элементы user, order, order_item и product. Я написал следующую спецификацию, где общая цена купленных предметов хранится в атрибуте total заказа: order_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, всего, user_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?)

Модель заказа связана со многими элементами order_items и принадлежит одному пользователю. Код для модели заказа выглядит следующим образом:

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

Может кто-нибудь сказать мне, почему он не сохраняет итоги? Это хранит пользователя, но не итоги. Что я делаю не так? Я использую rspec и капибару для тестирования.

Пожалуйста, помогите. Заранее спасибо.

Ответы [ 3 ]

0 голосов
/ 17 ноября 2018

Вместо придания некоторого фиксированного значения итоговому Создайте элементы order_items, соответствующие порядку в спецификации. Затем напишите спецификацию, ожидающую, что итоговое значение будет равно значению, которое будет рассчитываться в соответствии с логикой в ​​вашем методе общей цены. Не уверен, какие поля у вас есть в таблице 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
0 голосов
/ 19 ноября 2018

Итак, после долгих исследований я обнаружил, что объект заказа не был создан должным образом из-за проверок. Также я немного запутался в ассоциациях. Но теперь я понял это. Правильный rspec выглядит следующим образом:

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

Thankyou

0 голосов
/ 17 ноября 2018

Проблема здесь в том, что вы испытываете один из положительных и отрицательных моментов обратных вызовов, который является уровнем косвенности.

Вы установили total, но затем при сохранении ваша модель пересчитывает общее количество. Я предполагаю, что у вас есть 0 item_unit_price и / или количество.

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

Итак, чтобы это исправить, измените тестирование, в результате которого сохраненные элементы order_items будут иметь ожидаемую сумму.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...