Home > OS >  Rspec test case logic for rails
Rspec test case logic for rails

Time:10-29

this is my model 'Order' and the 'Order_item' model has association with it


class Order < ApplicationRecord has_many :order_items belongs_to :user

before_save :set_subtotal

def subtotal
  order_items.collect { |order_item| order_item.valid? ? order_item.unit_price * order_item.quantity : 0 }.sum
end

private

def set_subtotal
  self[:subtotal] = subtotal
end

end


2nd model:

class OrderItem < ApplicationRecord
  belongs_to :product
  belongs_to :order
  
  before_save :set_unit_price
  before_save :set_total
  
  def unit_price
    # If there is a record
  if persisted? 
      self[:unit_price]
    else
      product.price
    end
  end

  def total
   return unit_price * quantity
  end

  private

  def set_unit_price
    self[:unit_price] = unit_price
  end

  def set_total
    self[:total] = total * quantity
  end
end

i am trying to check the test case of RSPEC for the 'SUbtotal' function but i can't seem to find the logic

Rspec model file: Order

# frozen_string_literal: true

require 'rails_helper'
RSpec.describe Order, type: :model do
  let(:user) { FactoryBot.create(:user) }
  let(:subtotal) { FactoryBot.create(:order, subtotal: 1000) }
  let(:items) { FactoryBot.create(:order_item)  }

  describe 'callbacks' do
    it { is_expected.to callback(:set_subtotal).before(:save) }
  end

  describe 'associations' do
    it { is_expected.to belong_to(:user) }
    it { is_expected.to have_many(:order_items) }
  end

  #Gives Error i dont know how to get this

  # describe 'subtotal' do
  #   it 'it should calculate the subtotal' do
  #     expect(Order.subtotal).to eq(1000)
  #   end
  # end
end

enter image description here

CodePudding user response:

It looks like you're trying to call an instance method on the class. If you change to call subtotal on an instance you'll see a different error.

Order.new.subtotal

should have that defined.

To get your call to work in the spec you would need the method defined on the class with self.

def self.subtotal
...
end

CodePudding user response:

Like @nikkypx already said you're calling an instance method on the class itself.

In your test setup you created an instance of Order named subtotal. So to make it work you'd have to change your test to:

expect(subtotal.subtotal).to eq(1000)

Now since you named your instances funky it sounds confusing. More logical would be to name the Order instance order.

let(:order) { FactoryBot.create(:order, subtotal: 1000) }
  • Related