Reputation: 1463
How do I test a method for a message using RSpec? Basically my method accepts 2 parameters and if the right details have been supplied they should see a success message. I have tried this:
DRINKS_MACHINE = {
'Coca Cola' => 2.99,
'Fanta' => 3.27,
'Beer' => 5.99
}
class Drink
def check_money(drink_selection, money_amount_paid)
amount_paid = money_amount_paid.to_f
if amount_paid <= 0
raise ArgumentError, 'Insert Money'
end
if not DRINKS_MACHINE.has_key?(drink_selection)
raise ArgumentError, "Invalid selection: #{drink_selection}"
end
cost = DRINKS_MACHINE[drink_selection]
if amount_paid < cost
remainder = amount_paid - cost
raise ArgumentError, "Not enough coins. Insert #{remainder} more!"
elsif
puts "Purchase Complete: #{drink_selection}"
end
end
end
I wish to test that when a valid selection and enough money is passed to the method the correct message is returned. In this case the message will also include the string variable that was passed to the method. I have tried the following: expect @method.check_money("Coca Cola", "5.00").raise ("Purchase Complete : Coca Cola")
. Have also tried @method.check_money("Coca Cola", "4.59").should eq ("Purchase Complete: Coca Cola")
Upvotes: 0
Views: 2343
Reputation: 84343
When you have problems testing a method, you need to simplify it rather than trying to solve for a big ball of mud.
Your syntax has a number of glaring problems. This isn't Code Review Stack Exchange, but I strongly recommend refactoring your code so that it's less confusing. In particular, I'd stop raising exceptions all over the place for likely results. You could make your life a lot simpler with a good case statement.
The following code exercises the core functionality you're looking for in your class:
class Drink
DRINKS_MACHINE = {
'Coca Cola' => 2.99,
'Fanta' => 3.27,
'Beer' => 5.99
}
def check_money(drink_selection, money_amount_paid)
amount_paid = money_amount_paid.to_f
cost = DRINKS_MACHINE[drink_selection]
if amount_paid < cost
remainder = amount_paid - cost
raise ArgumentError, "Not enough coins. Insert #{remainder} more!"
else
"Purchase Complete: #{drink_selection}"
end
end
end
describe Drink do
describe '#check_money' do
it 'sells a drink' do
subject.check_money('Coca Cola', 2.99).should == "Purchase Complete: Coca Cola"
end
end
end
In particular, you need to return a result from your method (#puts returns nil) and ensure that your DRINKS_MACHINE constant is available to both your class and your spec.
Upvotes: 2
Reputation: 29291
There are two different problems here, one with your spec and another in your method.
In your spec, you should use eq
as a matcher since you're expecting a returned string from the check_money
method.
@method.check_money("Coca Cola", "5.00").should eq("Purchase Complete: Coca Cola")
In your method, you should use simply
"Purchase Complete: #{drink_selection}"
and get rid of the puts
, because that's outputting to console instead of returning the string.
Also, switch elsif
for else
in the previous line.
Upvotes: 2