我有一种方法' current_balance'在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 the 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 be YYYY-MM-DD"}
validates :status, presence: true
def self.next_due
where("due_date >= ? AND 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 < ? AND 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
then self.status = "Open"
elsif self.current_balance < 0
then self.status = "Overpaid"
elsif self.current_balance = 0
then self.status = "Paid"
end
end
end
工厂,发票.rb
FactoryGirl.define do
factory :invoice do
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 do
currency nil
end
end
模型规范,invoices_spec.rb包含:
require "spec_helper"
describe Invoice, '#current_balance' do
it "calculates the current balance of an invoice" do
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 do
before(:all) { @invoice = FactoryGirl.build(:invoice) }
it "has a valid factory" do
expect(FactoryGirl.create(:invoice)).to be_valid
end
it "is invalid without a number" do
invoice = Invoice.new(number: nil)
expect(invoice).to_not be_valid
end
it "is invalid without a currency" do
invoice = Invoice.new(currency: nil)
expect(invoice).to_not be_valid
end
it "is invalid without a total_due" do
invoice = Invoice.new(total_due: nil)
expect(invoice).to_not be_valid
end
it "is invalid without a due_date" do
invoice = Invoice.new(due_date: nil)
expect(invoice).to_not be_valid
end
it "is invalid without a status" do
invoice = Invoice.new(status: nil)
expect(invoice).to_not be_valid
end
end
该方法运行良好,并在运行应用程序时计算发票的当前余额。但是,当我运行模型规范时,我收到错误。
#current_balance&#39; &安培; &#39;它有一个有效的工厂&#39;示例通过,其余的都失败并出现相同的错误。
Failure/Error: expect(invoice).to_not be_valid
NoMethodError:
undefined method `-' for nil:NilClass
我做错了什么?
答案 0 :(得分:0)
啊,对于完整的型号代码,问题非常清楚。这一切都从这一行开始:
validates :status, presence: true
触发status
的getter,触发current_balance
的getter,通过从self.current_balance
中减去未设置的内容(total_due
)来设置nil
在所有那些失败的测试用例中。因此错误信息。