Жасмин издевались обещание метод не вызывает затем блок

У меня возникли проблемы с получением издевательского метода, который возвращает обещание вызвать то, что тогда было подключено к нему.

Вот тестируемый сервис. Важным аспектом является метод get.

angular.module('service.overtimeRules').factory('OvertimeRules', OvertimeRules);

function OvertimeRules(_, Message, OvertimeRulesModel) {
    const rules = [];

    return { get };

    function get() {
        return OvertimeRulesModel.get().then(
            data => {
                console.log('This never fires :(');
                rules.push(...data);
            },
            () => Message.add('Error retrieving the overtime rules.', 'danger')
        );
    }
}

Вот файл spec. Ошибка, которую я получаю TypeError: undefined is not an object (evaluating 'OvertimeRulesModel.get'). Если удалить оболочку get describe, ошибка исчезнет, но блок метода службы thenпо-прежнему не срабатывает.

describe('OvertimeRules', () => {
    let $q, $rootScope, deferred, Message, OvertimeRules, OvertimeRulesModel;

    beforeEach(() => {
        module('globals');
        module('service.overtimeRules');
        module($provide => {
            $provide.value('Message', Message);
            $provide.value('OvertimeRulesModel', OvertimeRulesModel);
        });

        inject((_$q_, _$rootScope_, _OvertimeRules_) => {
            $q = _$q_;
            $rootScope = _$rootScope_;
            OvertimeRules = _OvertimeRules_;

            deferred = { OvertimeRulesModel: { get: $q.defer(), update: $q.defer } };

            Message = jasmine.createSpyObj('Message', ['add']);

            OvertimeRulesModel = jasmine.createSpyObj('OvertimeRulesModel', ['get']);
            OvertimeRulesModel.get.and.returnValue(deferred.OvertimeRulesModel.get.promise);
        });
    });

    describe('get', () => { // why would this cause an error?
        it('gets a list of rules and pushes them into the rules array', () => {
            deferred.OvertimeRulesModel.get.resolve(['rules']);
            OvertimeRules.get();
            $rootScope.$digest(); // $apply doesn't work either
            expect(OvertimeRules.rules).toEqual(['rules']);
        });
    });
});

Возможно, важные Примечания:

  • Я рад подойти к этому по-другому, пока код лаконичен и читаем. Кроме того, мне также нужно отвергать обещания.
  • OvertimeRulesModel другая фабрика в этом service.overtimeRulesмодуле; Messageчасть отдельно модуля.
  • Я попытался перейти OvertimeRulesModelна свой собственный модуль, но получил ту же ошибку.
  • Я использую
    A = jasmine.createSpyObj(...); A.get.and.returnValue(promise);
    подход в спецификации контроллера и все работает нормально
  • Это модульные тесты, поэтому я бы предпочел избежать введения фактического OvertimeRulesModelобслуживания.

1 ответ

  1. Лучший ответ

    Кажется, что я потерял ссылку на переменные, поставляемые поставщику модуля. Решение состоит только в том, чтобы переместить createSpyObjвызовы выше $provideоператора.

    ...
    module('service.overtimeRules');
    
    Message = jasmine.createSpyObj('Message', ['add']);
    OvertimeRulesModel = jasmine.createSpyObj('OvertimeRulesModel', ['get']);
    
    module($provide => {
        $provide.value('Message', Message);
        $provide.value('OvertimeRulesModel', OvertimeRulesModel);
    });
    ...
    

    Going with solution исправлена еще одна проблема, с которой я столкнулся. Кроме того, мне не пришлось менять returnValueсинтаксис.

    Старый ответ:

    И, по-видимому, все, что мне нужно было сделать, это изменитьreturnValue, чтобы callFakeтак нравиться:

    OvertimeRulesModel = jasmine.createSpyObj('OvertimeRulesModel', ['get']);
    OvertimeRulesModel.get.and.callFake(() => deferred.OvertimeRulesModel.get.promise);