I am doing an online exercise. I am asked to create an InterestCalculator
class that takes four arguments on initialization and defines two functions, amount
and statement
. I have to use the self
method throughout the class. Instance variables should only be directly accessed in the initialize
function and amount
should only be calculated in one place.
Here are the specs:
describe InterestCalculator do
before { @calc = InterestCalculator.new(500, 0.05, 4, 5) }
describe "#amount" do
it "calculates correctly" do
expect( @calc.amount ).to eq(610.1)
end
end
describe "#statement" do
it "calls amount" do
@calc.stub(:amount).and_return(100)
expect( @calc.statement ).to eq("After 4 years I'll have 100 dollars!")
end
end
end
And here is my code:
class InterestCalculator
attr_accessor :amount, :statement
def initialize(principal, rate, years, times_compounded)
@principal = principal
@rate = rate
@years = years
@times_compounded = times_compounded
end
def self.amount
amount = principal * (1 + rate / times_compounded) ** (times_compounded * years)
end
def self.statement
statement = "After #{years} years i'll have #{amount} dollars"
end
end
I keep getting the following error and don't know why:
RSpec::Expectations::ExpectationNotMetError
expected: 610.1
got: nil
RSpec::Expectations::ExpectationNotMetError
expected: "After 4 years I'll have 100 dollars!"
got: nil
If you intend amount
and statement
to be instance methods then change your code to
def amount
@amount ||= @principal * (1 + @rate / @times_compounded) ** (@times_compounded * @years)
end
def statement
@statement ||= "After #{@years} years i'll have #{amount} dollars"
end
this is because
def self.my_method
# method body
end
creates a class method. Also, if you want amount
and statement
to be read-only change attr_accessor
to attr_reader
.