Home > OS >  RSpec: How to test call of another classes method inside of a method?
RSpec: How to test call of another classes method inside of a method?

Time:09-15

So I have some classes in a gem and I'm struggling to test specific lines in my code. The class Foo has two attributes, both of which are instances of classes User and Client. How can I test that Foo.get_events(date) calls the method Client.get_events(user, date)?

class Foo
  attr_reader(:user, :client)

  def get_events(date)
    client.get_events(user[:id], date)
  end
end
class Client
  def get_events
    # Makes API call here
  end
end

I already have mocked requests for Client.get_events and that method is successfully tested, but I can't figure out how to test that Foo.get_events calls that method.

Thank you!

CodePudding user response:

I would do this:

describe 'Foo#get_event' do
  let(:client) { instance_double(Client) }
  let(:user) { { id: 'user_id' } } 
  let(:date) { Date.today }

  subject(:foo) { Foo.new(user, client) } 

  before { allow(client).to receive(:get_events).and_return(true) }
  
  it "delegates to the client's method" do
    foo.get_event(date)

    expect(client)
      .to have_recieved(:get_events)
      .with('user_id', date)
      .once
  end
end

I assumed that user is a hash because of the user[:id] call. The instance of Foo might need to be initialized differently to set user and client but you didn't share what your initialize method looks like.

Furthermore, you will notice that your test will fail immediately because you pass two arguments to client.get_events(user[:id], date), but the method definition in Client doesn't accept any arguments. It probably has to change to something like this:

class Client
  def get_events(user_id, date)
    # Makes API call here
  end
end
  • Related