5

I have a service MyService with a function using the ga() event tracking call which I want to test:

angular.module('myModule').factory('MyService', [function() {

    var myFunc = function() {
        ga('send', 'event', 'bla');
        // do some stuff
    }

    return {
        myFunc: myFunc
    }
]);

My spec file looks like this:

describe('The MyService', function () {

    var MyService,
        ga;

    beforeEach(function () {
        module('myModule');
        ga = function() {};
    });

    beforeEach(inject(function (_MyService_) {
        MyService = _MyService_;
    }));

    it('should do some stuff', function () {
        MyService.myFunc();
        // testing function
    });
});

Running my tests always gives me:

ReferenceError: Can't find variable: ga

alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
DonJuwe
  • 4,477
  • 3
  • 34
  • 59
  • If you want to test a service, you should not be using Protractor. Protractor is designed for developing and running *end-to-end tests*, testing your application as a whole from a user's perspective in a browser. – alecxe Apr 22 '16 at 12:48
  • sorry, I am, of course, talking about unit testing - changed my text – DonJuwe Apr 22 '16 at 12:51
  • 1
    ga is defined inside the function, is not global. Try with window.ga = function() {} – fantarama Apr 22 '16 at 12:55

3 Answers3

7

The problem is global scope of ga.

The ga variable that you create inside your tests has a local scope and will not be visible to your own service.

By using a global variable (ga) you have made unit testing difficult.

The current option would be to either create a angular service to wrap gaand use that everywhere else. Such service can be mocked too.

The other option is to override the global ga. But this will have side effects.

window.ga=function() {}

Chandermani
  • 42,589
  • 12
  • 85
  • 88
5

After trying different solution I finally fixed with below code.

beforeAll( ()=> {
    // (<any>window).gtag=function() {} // if using gtag
    (<any>window).ga=function() {}
})
Shabbir Dhangot
  • 8,954
  • 10
  • 58
  • 80
0

Slightly out of date, but I am trying to leverage ReactGA and mocked creating an event like:

it('should do something...', () => {
    const gaSpy = jest.spyOn(ReactGA, 'ga');
    someService.functionThatSendsEvent({ ...necessaryParams });
    expect(gaSpy).toHaveBeenCalledWith('send', 'event',
       expect.objectContaining({/*whatever the event object is supposed to be*/}
    );
});

This is helpful if youre sending specific data to an angular/reactjs service which is then sending it to GA.

Tyler Russell
  • 299
  • 2
  • 10