在承诺之后如何让karma / jasmine单元测试与回调一起工作?

问题描述 投票:0回答:1

我正在AngularJS 1.5,JavaScript和Cordova中编写应用程序。

我想编写一个单元测试,它将检查是否在承诺之后执行了某些代码。

这是我的codepen:https://codepen.io/aubz/pen/yrxqxE

我不知道为什么但是单元测试一直在说这个错误:预期的间谍尝试GeoClocking已被调用。

这很奇怪,因为控制台日志打印出来,因此实际上正在调用该函数。

it('if location services are on, proceed', function () {

    spyOn(CordovaDiagnostics, 'getLocationServicesStatus').and.callFake(function () {
        return Promise.resolve(true);
    });

    spyOn(Clocking, 'attemptGeoClocking').and.callFake(function () {});

    Clocking.geolocationClocking();

    expect(Clocking.attemptGeoClocking).toHaveBeenCalled();

});


function geolocationClocking() {

    CordovaDiagnostics
        .getLocationServicesStatus()
        .then(attemptGeoClocking)
        .catch(function () {});
}

function attemptGeoClocking() {
    console.log(' here ');
}
angularjs unit-testing callback karma-jasmine
1个回答
1
投票

基本上你是在监视错误的功能。让我重命名一些事情,以便更清楚你在做什么:

function Clocking(CordovaDiagnostics) {

    return {
        geolocationClocking: geolocationClocking,
        attemptGeoClockingOUTER: attemptGeoClockingINNER//private API
    };

    function geolocationClocking() {

        CordovaDiagnostics
            .getLocationServicesStatus()
            .then(attemptGeoClockingINNER)
            .catch(function () {});
    }

    function attemptGeoClockingINNER() {
        console.log(' here ');
    }
}

在测试中:

spyOn(Clocking, 'attemptGeoClockingOUTER').and.callFake(function () {
      console.log('calling fake')
 });

正如您所看到的,您的代码正在监视OUTER,但geolocationClocking从不调用OUTER,它使用的是INNER:

CordovaDiagnostics
            .getLocationServicesStatus()
            .then(attemptGeoClockingINNER)

您需要以这样的方式重新编写代码,使其在内部使用与您在测试中存根的函数相同的函数。这是一个工作的codepen:https://codepen.io/anon/pen/xeyrqy?editors=1111

注意:我也用Promise.resolve替换了$q.when并添加了$rootScope.$apply(),这是解决这些承诺所必需的。

添加我在这里所做的更改,以防codepen消失:

我已将工厂更改为服务(虽然没有必要,但我更喜欢在这种情况下使用服务):

myApp.service("Clocking", Clocking);

function Clocking(CordovaDiagnostics) {

    this.geolocationClocking = function() {

        CordovaDiagnostics
            .getLocationServicesStatus()
            .then(() => this.attemptGeoClocking())
            .catch(function () {});
    }

    this.attemptGeoClocking = function() {
        console.log(' here ');
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.