Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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!

like image 810
akaplo Avatar asked Sep 15 '26 02:09

akaplo


1 Answers

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.

like image 173
Paul Samsotha Avatar answered Sep 16 '26 18:09

Paul Samsotha



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!