【问题标题】:How do you use unit test a factory using $provide and $q您如何使用 $provide 和 $q 对工厂进行单元测试
【发布时间】:2018-04-13 15:39:47
【问题描述】:

我正在尝试为依赖于另一个返回承诺的工厂函数的服务编写单元测试。我已经按照questionanswer 中的流程进行了操作,但由于某种原因,我试图验证的 then() 中的代码没有被调用。我怎样才能让它工作?如果可能,我想使用不执行 spyOn 的版本(答案中的更新部分)。

var app = angular.module('test', []);

app.factory('managerService', (managerModel) => {
    var service = {
        getCurrentUser: getCurrentUser
    }

    function getCurrentUser() {
        return managerModel.api.get();
    }
    return service;
})

describe('promise with provider', () => {
    var managerModelMOCK = {
        api: {}
    };
    var $q;
    var $rootScope;
    var deferredUser;
    //   beforeEach(inject(()=> {})) //no inject here: Injector already created, can not register a module!

    beforeEach(angular.mock.module('test'));

    beforeEach(() => {
        angular.mock.module(function ($provide) {
            $provide.value('managerModel', managerModelMOCK); // override version here
        });
    });

    beforeEach(inject(($q) => {
        deferredUser = $q.defer();
        managerModelMOCK.api.get = () => {
            return deferredUser.promise;
        }
    }));


    it('should resolve a promise', angular.mock.inject((managerService, $rootScope) => {
        expect(managerService).toBeDefined();
        var expected = {
            Name: 'Somebody'
        };
        var actual;

        //this doesn't work either
        // var innerPromise = $q.defer();
        // innerPromise.resolve(expected);

        // managerModel.api.get = () => innerPromise.promise;

        deferredUser.resolve(expected);

        $rootScope.$apply();

        managerService.getCurrentUser()
            .then((user) => {
                actual = user;
            });

        //undefined, why?
        expect(actual).toBeDefined();
    }))
})

【问题讨论】:

  • 完全不确定什么是正确的,什么不是。所以我基本上在这里留下一些有用的东西: var mockResultPromise; var apiMock = {get: () => { return mockResultPromise}}; ... $provide.value('managerModel', () => apiMock); ... it('', () => { mockResultPromise = $q.when({Name: 'something'}); var actual; managerService.getCurrentUser() .then((user) => { actual = user; }); // 实际未定义 $rootScope.$apply(); expect(actual).toBeDefined(); })

标签: javascript angularjs unit-testing jasmine angularjs-ngmock


【解决方案1】:

呃,答应菜鸟的错误。承诺链中的then() 函数需要return,所以这段代码可以工作:

    managerService.getCurrentUser()
        .then((user) => {
            actual = user;
            //promise chains have to return
            return;
        });

    //rootscope.$apply() had to be moved
    $rootScope.$apply();

我之前曾尝试将 `$rootScope.$apply() 放在 Promise 链之后,但当然没有 return 在那里仍然无法正常工作。

【讨论】:

    猜你喜欢
    • 2011-06-23
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-12
    相关资源
    最近更新 更多