ruby on rails - RSpec throws a NoMethodError, but method works in the app -
i have method 'current_balance' defined in invoice.rb:
class invoice < activerecord::base belongs_to :purchase has_many :payments, dependent: :destroy validates :number, presence: true validates :currency, format: {with: /\a[a-z]+\z/, message: "please enter 3 letter currency code in caps."} validates :total_due, presence: true validates :due_date, format: {with: /\d{4}-\d{2}-\d{2}/, message: "format must yyyy-mm-dd"} validates :status, presence: true def self.next_due where("due_date >= ? , status = ?", time.now, 'open').order("due_date desc").first ? where("due_date >= ?", time.now).order("due_date desc").first.due_date : '' end def self.overdue where("due_date < ? , status = ?", time.now, 'open').order("due_date desc").first ? where("due_date < ?", time.now).order("due_date desc").first.due_date : '' end def current_balance self.current_balance = (self.total_due - self.payments.sum(:amount_paid)) end def status if self.current_balance > 0 self.status = "open" elsif self.current_balance < 0 self.status = "overpaid" elsif self.current_balance = 0 self.status = "paid" end end end
the factory, invoices.rb
factorygirl.define factory :invoice sequence(:id) { |number| number } sequence(:purchase_id) { |n| n } number { ffaker::string.from_regexp(/\a[a-za-z0-9]+\z/) } terms { ffaker::string.from_regexp(/\a[a-za-z0-9\s]+\z/) } currency { ffaker::string.from_regexp(/\a[a-z]+\z/) } total_due {'200.00'} due_date { ffaker::time.date } notes { ffaker::hipsteripsum.paragraph } status {[:open, :paid, :canceled].sample} end factory :invalid_invoice, parent: :invoice currency nil end end
the model spec, invoices_spec.rb contains:
require "spec_helper" describe invoice, '#current_balance' "calculates current balance of invoice" invoice = factorygirl.create(:invoice, total_due: 200) invoice.payments << factorygirl.create(:payment, amount_paid: 100) invoice.payments << factorygirl.create(:payment, amount_paid: 50) expect(invoice.current_balance).to eq(50) end end describe invoice before(:all) { @invoice = factorygirl.build(:invoice) } "has valid factory" expect(factorygirl.create(:invoice)).to be_valid end "is invalid without number" invoice = invoice.new(number: nil) expect(invoice).to_not be_valid end "is invalid without currency" invoice = invoice.new(currency: nil) expect(invoice).to_not be_valid end "is invalid without total_due" invoice = invoice.new(total_due: nil) expect(invoice).to_not be_valid end "is invalid without due_date" invoice = invoice.new(due_date: nil) expect(invoice).to_not be_valid end "is invalid without status" invoice = invoice.new(status: nil) expect(invoice).to_not be_valid end end
the method works , calculates current balance of invoice when run app. when run model spec, however, error.
the '#current_balance' & 'it has valid factory' examples pass, rest fail same error.
failure/error: expect(invoice).to_not be_valid nomethoderror: undefined method `-' nil:nilclass
what doing wrong?
ah, full model code problem crystal clear. starts line:
validates :status, presence: true
it triggers getter of status
, triggers getter of current_balance
sets self.current_balance
subtracting total_due
not set (is nil
) in of failing test cases. hence error message.
Comments
Post a Comment