Question

I have class like below

#bank.rb
class Bank
   def transfer(customer1, customer2, amount_to_transfer)
      if customer1.my_money >= amount_to_transfer
        customer1.my_money -= amount_to_transfer
        customer2.my_money += amount_to_transfer
      else
        return "Insufficient funds"
      end 
   end 
end

class Customer
  attr_accessor :my_money

  def initialize(amount)
    self.my_money = amount
  end 
end

And my spec file looks as below:

#spec/bank_spec.rb
require './spec/spec_helper'
require './bank'

describe Bank do
  context "#transfer" do
    it "should return insufficient balance if transferred amount is greater than balance" do
    customer1 = Customer.new(500)
    customer2 = Customer.new(0)

    customer1.stub(:my_money).and_return(1000)
    customer2.stub(:my_money).and_return(0)

    expect(Bank.new.transfer(customer1, customer2, 2000)).to eq("Insufficient funds")
    expect(customer1).to have_received(:my_money) # This works
    customer1.should_receive(:my_money) #throws error 
   end 
  end 
end

As per https://relishapp.com/rspec/rspec-mocks/v/2-14/docs/message-expectations both expect and should_receive are same but expect is more readable than should_receive. But why it is failing? Thanks in advance.

Was it helpful?

Solution

place this line:

customer1.should_receive(:my_money)

before

expect(Bank.new.transfer(customer1, customer2, 2000)).to eq("Insufficient funds")

expect to have_received and should_receive have diffent meaning

expect to have_received passes if object already received expected method call while should_receive passes only if object will receive expected method call in future (in scope of current testcase)

if you would write

expect(customer1).to receive(:my_money)

instead of

expect(customer1).to have_received(:my_money)

it would fail too. Unless you place it before the line which calls this method.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top