#ruby #rspec
#рубиновый #rspec
Вопрос:
В моем классе транзакций есть метод ‘balance’, который вызывает метод ‘balance_after’ из моего класса Account. Я хотел бы провести тест, в котором я мог бы проверить, вызывается ли метод ‘balance_after’ с помощью метода ‘balance’. Я новичок как в ruby, так и в тестировании, поэтому я ценю любые рекомендации! Я использую simple-cov для получения своего покрытия, и я хотел бы достичь 100%, если это возможно. Надеюсь, я предоставил достаточно информации. Заранее спасибо!
Failures:
1) Transaction#balance checks balance
Failure/Error: @account.balance_after(self)
NoMethodError:
undefined method `balance_after' for :account:Symbol
# ./lib/transaction.rb:11:in `balance'
# ./spec/transaction_spec.rb:19:in `block (3 levels) in <top (required)>'
Finished in 0.04089 seconds (files took 0.87223 seconds to load)
10 examples, 1 failure
Failed examples:
rspec ./spec/transaction_spec.rb:18 # Transaction#balance checks balance
COVERAGE: 98.55% -- 68/69 lines in 4 files
---------- -------------------- ------- -------- ---------
| coverage | file | lines | missed | missing |
---------- -------------------- ------- -------- ---------
| 90.91% | lib/transaction.rb | 11 | 1 | 16 |
---------- -------------------- ------- -------- ---------
Мой класс транзакций
class Transaction
attr_reader :amount, :account, :timestamp
def initialize(amount, account)
@amount = amount
@account = account
@timestamp = Time.now.strftime("%d/%m/%Y")
end
def balance
@account.balance_after(self)
end
def formate
@amount > 0 ? (puts "#{@timestamp}|| #{@amount} || || #{balance}")
: (puts "#{@timestamp}|| || #{@amount.abs} || #{balance}")
end
end
Мой класс учетной записи
require_relative 'transaction'
class Account
attr_reader :balance, :transactions
HEADER = 'date || credit || debit || balance'
def initialize
@balance = 0
@transactions = []
end
def deposit(amount)
@balance = amount
@transactions << Transaction.new(amount, self)
end
def withdraw(amount)
@balance -= amount
@transactions << Transaction.new(-amount, self)
end
def balance_after(transaction)
index = @transactions.find_index(transaction)
@transactions[0..index].map(amp;:amount).sum
end
def print_statement
puts HEADER
@transactions.reverse.map(amp;:formate)
end
end
Моя спецификация транзакции
require 'transaction'
describe Transaction do
let(:transaction) { Transaction.new(:amount, :account) }
let(:timestamp) { Time.now.strftime('%d/%m/%Y') }
describe '#initilalize' do
it 'validates class' do
expect(transaction).to be_a Transaction
end
it 'stores dates' do
expect(transaction.timestamp).to eq timestamp
end
end
describe '#balance' do
it 'checks balance' do
expect(transaction.balance).to eq true
end
end
end
Ответ №1:
Вы должны правильно вызвать метод. Transaction.new
принимает сумму, предположительно число, и какой-то balance_after
определенный объект Account. Вы дали ему два символа.
describe Transaction do
let(:account) { Account.new }
let(:amount) { 1.23 }
let(:transaction) { Transaction.new(amount, account) }
let(:timestamp) { Time.now.strftime('%d/%m/%Y') }
Затем убедитесь, что он возвращает то, что вы ожидаете. balance
не возвращает true или false, он возвращает баланс. В частности, это просто переход к account.balance_after(transaction)
, так что проверьте это.
describe '#balance' do
it 'checks balance' do
expect(transaction.balance).to eq account.balance_after(transaction)
end
end
Это может показаться циклическим, но это всего лишь интеграционный тест. account.balance_after
будет проходить модульное тестирование в рамках тестов учетной записи. Здесь нет необходимости повторять эти тесты.
Комментарии:
1. Привет, Шверн, спасибо за помощь! Это получило еще некоторое покрытие, что прекрасно, но некоторые строки все еще отсутствуют, по-видимому, поэтому я предполагаю, что это будет решено, как только я протестирую метод formate в классе Transaction?. Вы упомянули, что метод balance не нужен, потому что он должен быть протестирован в классе Account . Будет ли это применимо к моему методу форматирования в транзакциях, потому что у меня есть print_statement в моем классе Account? Еще раз спасибо!
2. @byronmac Вам не нужно проводить тщательное тестирование
Transaction#balance
, потому что это просто оболочка,Accountt#balance_after
и это лучше описано в тестахAccount#balance_after
. Вам нужно протестироватьTransaction#formate
, потому что это весь код внутриTransaction
. Посмотрите «интеграционный тест» против «модульного теста».3. @byronmac Кстати, код в
formate
может быть простымputs "#{@timestamp}|| || #{@amount.abs} || #{balance}"
. Абсолютное значение числа одинаково, независимо от того, положительное оно или отрицательное.