ReferenceError: ga is not defined [Ionic 2.2 Unit Testing With Karma]

google-analytics, ionic-framework, ionic2, karma-jasmine, unit-testing

Solution

You declare the var `ga` but that is just to make TypeScript happy. At runtime, the `ga` is made global from some external script. But this script is not included in the test.

What you could do is just add the (mock) function to the `window` for the tests. You could probably do this in your `karma-test-shim.js`.

window.ga = function() {}

Or if you wanted to test that the component is calling the function with the correct arguments, you could just add the function separately in each test that uses the function. For example

beforeEach(() => {
  (<any>window).ga = jasmine.createSpy('ga');
});

afterEach(() => {
  (<any>window).ga = undefined;
})

Then in your test

it('..', () => {
  const fixture = TestBed.creatComponent(MyBusesComponent);

  expect(window.ga.calls.allArgs()).toEqual([
    ['set', 'page', '/my-buses.html'],
    ['send', 'pageview']
  ]);
})

Since you're making multiple calls to `ga` in the constructor, the `Spy.calls` will get the argument of all each call and put them in separate arrays.

Problem

I'm adding unit tests to an Ionic 2.2.0 app I manage, but my Components crash at test-time when they encounter Google Analytics code. I'm using Ionic's official unit testing example as a basis, and my current progress can be seen on our public repo. My project uses Google Analytics, which is added to the HTML and downloaded at runtime (because we have different keys for development vs production). The code that initializes Analytics is in my `main.ts`, and it sets a global variable `ga`, which is subsequently available throughout the application. I'm beginning the tests for the app's first page, which uses Analytics. When I run the tests, I'm met with the following error Component should be created FAILED ReferenceError: ga is not defined at new `MyBusesComponent` (webpack:///src/pages/my-buses/my-buses.component.ts:33:6 <- karma-test-shim.js:138419:9) at new Wrapper_MyBusesComponent (/DynamicTestModule/MyBusesComponent/wrapper.ngfactory.js:7:18) at CompiledTemplate.proxyViewClass.View_MyBusesComponent_Host0.createInternal (/DynamicTestModule/MyBusesComponent/host.ngfactory.js:15:32) ........ This is because `main.ts` doesn't seem to be loaded or executed, and I assume TestBed is doing that purposefully. It's certainly better that I don't have the actual Google Analytics object, but the Component does need a function called `ga`. My question, therefore, is as follows: how can I create Google Analytics' `ga` variable in my test configuration such that it's passed through to my components at test-time? I've tried exporting a function from my `mocks` file and adding it to either the `imports` or `providers` arrays in my spec file, but to no avail. I appreciate any advice! Feel free to check my code at our repo I linked to above and ask any followups you need. Thanks!

Original source