如何模拟 Google Analytics 函数调用 ga()

5

我有一个服务MyService,其中有一个使用ga()事件追踪调用的函数,我想要测试它:

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

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

    return {
        myFunc: myFunc
    }
]);

我的规范文件看起来像这样:

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
    });
});

运行我的测试总是会出现以下错误:

引用错误:找不到变量:ga


如果你想测试一个服务,你不应该使用Protractor。Protractor是为开发和运行端到端测试而设计的,从用户在浏览器中的角度来测试你的整个应用程序。 - alecxe
抱歉,我当然是在谈论单元测试 - 改变了我的文本。 - DonJuwe
1
ga被定义在函数内部,不是全局的。尝试使用window.ga = function() {}。 - fantarama
3个回答

7
问题在于 ga 的全局作用域。
在测试中创建的 ga 变量具有本地作用域,无法被您自己的服务看到。
通过使用全局变量 (ga),你让单元测试变得困难。
目前的选择是要么创建一个 Angular 服务来包装 ga 并在其他地方使用它。这种服务也可以被模拟。
另一种选择是覆盖全局的 ga。但这将产生副作用。 window.ga=function() {}

谢谢,有没有办法在全局变量上进行间谍或拦截? - DonJuwe
1
你可以尝试使用 spyOn(window, 'ga'); - Chandermani
同样对于dataLayerwindow.dataLayer = { push: function() {} } - joshy

5

尝试了不同的解决方案之后,我终于通过以下代码修复了问题。

beforeAll( ()=> {
    // (<any>window).gtag=function() {} // if using gtag
    (<any>window).ga=function() {}
})

0
稍微有点过时,但我正在尝试利用ReactGA并模拟创建一个事件,就像这样:
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*/}
    );
});

如果您需要将特定数据发送到 Angular/ReactJS 服务,然后再将其发送到 GA,则这非常有用。


我没有使用ReactGA,但想要用GA4测试我的/collect调用。我应该使用什么? - Joshua Shibu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接