【问题标题】:Jasmine mocked promise method doesn't trigger then blockJasmine 模拟的 Promise 方法不会触发然后阻塞
【发布时间】:2017-03-17 15:50:37
【问题描述】:

我在获取一个返回承诺以触发 then 连接到它的模拟方法时遇到问题。

这是正在测试的服务。 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')
        );
    }
}

这是规范文件。我得到的错误是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 服务。

【问题讨论】:

    标签: angularjs unit-testing jasmine karma-jasmine angular-mock


    【解决方案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);
    });
    ...
    

    使用解决方案解决了我遇到的另一个问题。此外,我不必更改 returnValue 语法。

    旧答案:

    显然,我需要做的就是将returnValue 更改为callFake,如下所示:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-03-04
      • 1970-01-01
      • 2023-03-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多