Ruby-on-rails – How to test if a method call with arguments happened in RSpec

rspecrubyruby-on-rails

In my Ruby app, I'm trying to test with RSpec a module method called with arguments from a controller.

The module in question is the EventTracker module to track analytics: https://github.com/doorkeeper/event_tracker

This is the situation:

  1. From my controller I call the method from the controller like below:

    class InvestorHomeController < ApplicationController
      def do_something
        track_event 'User Action'
      end
    end
    
  2. The track_event method is defined inside the EventTracker module, like the following:

    module EventTracker
      module HelperMethods
        def track_event(event_name, args = {})
          (session[:event_tracker_queue] ||= []) << [event_name, args]
      end
    end
    

    end

  3. I tried different solutions, but nothing worked for me. Like:

    expect(controller).to receive(:track_event).with('User Action')
    expect(EventTracker).to receive(:track_event).with('User Action')
    

The first it didn't work because track_event is not a method of the controller,
and for the second one I've got the error below:

RSpec::Mocks::MockExpectationError: (EventTracker).track_event("User Action")
expected: 1 time with arguments: ("User Action")
received: 0 times

Anyone knows how to test this kind of methods with RSpec?

Thanks,
D.

Best Answer

I've found the way to get this working!

Basically, I was doing everything right apart from doing the 'post' call in the right place.

The post call have to be done after the:

  expect(controller).to receive(:track_event).with('User Action')

i.e. the code below will work without any problems:

  expect(controller).to receive(:track_event).with('User Action')
  post :new_user_action_post

and not before.

I hope will help someone! ;)

D.