user9697411
user9697411

Reputation:

test that method was called inside another method with rspec

I have to write a spec for the following method:

def track_event
  tracker = set_tracker
  category = define_event_category
  tracker.event(category: category, action: name, label: properties['short_name'], value: properties['paid'])
end

To be specific I have to to check if method event is called on the variable tracker when track_event is called. I tried to do it like this:

describe '#track_event' do
  it 'should call event method' do
    expect(tracker).to receive(:event)
  end
end

and got an error undefined local variable or method 'tracker'. What do I do wrong?

Upvotes: 3

Views: 9986

Answers (2)

Jagdeep Singh
Jagdeep Singh

Reputation: 4920

Assuming in your rspecs, subject is the instance of class where track_event method is defined, you can stub the value returned from set_tracker to an object defined by you and then check if the method event is called on that tracker object.

 describe '#track_event' do
   # Build a tracker object
   let(:tracker) { <Whatever type of object you expect as a tracker> }

   # Stub the output of `set_tracker`
   before { allow(subject).to receive(:set_tracker) { tracker } }

   it 'should call event method' do
     expect(tracker).to receive(:event)
   end

   after { subject.track_event }
 end

I would recommend verifying the arguments too with the method call.

Upvotes: 0

Stefan
Stefan

Reputation: 114248

You cannot access tracker because it is a local variable.

You could stub your set_tracker method instead and return an instance double:

describe '#track_event' do
  let(:tracker_double) { instance_double(Tracker) }

  it 'should call event method' do
    allow(foo).to receive(:set_tracker).and_return(tracker_double)
    expect(tracker_double).to receive(:event)
    foo.track_event
  end
end

foo is your test subject.

Upvotes: 4

Related Questions