Как заставить модульные тесты кармы / жасмина работать с обратным вызовом после обещания? - PullRequest
0 голосов
/ 23 апреля 2019

Я пишу приложение на AngularJS 1.5, JavaScript и Cordova.

Я хочу написать модульный тест, который проверит, был ли выполнен какой-либо код после обещания.

Вот мой код: 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 ');
}

1 Ответ

1 голос
/ 24 апреля 2019

По сути, вы шпионите за неправильными функциями.Позвольте мне переименовать несколько вещей, чтобы было более понятно, что вы делаете:

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

Как видите, ваш код шпионит заВНЕШНИЙ, но geolocationClocking никогда не вызывает ВНЕШНИЙ, он использует ВНУТРЕННИЙ:

CordovaDiagnostics
            .getLocationServicesStatus()
            .then(attemptGeoClockingINNER)

Вам нужно будет переделать ваш код таким образом, чтобы он использовал ту же функцию, что и выповторно заглушки в вашем тесте.Вот рабочий код: https://codepen.io/anon/pen/xeyrqy?editors=1111

Примечание: я также заменил Promise.resolve на $q.when и добавил $rootScope.$apply(), это необходимо для разрешения обещаний.

Добавление изменений, которые я сделал здесь, на случай, если кодовая ручка когда-нибудь исчезнет:

Я изменил фабрику на сервис (хотя в этом нет необходимости, я предпочитаю использовать сервисы в этом случае):

myApp.service("Clocking", Clocking);

function Clocking(CordovaDiagnostics) {

    this.geolocationClocking = function() {

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

    this.attemptGeoClocking = function() {
        console.log(' here ');
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...