如何测试一个装饰器,它是一个围绕$timeout的包装器



我有以下装饰器,从$rootScope中包装原始$timeout。当在控制器内部使用时,它将有助于在作用域被破坏时取消$timeout承诺。

angular.module('MyApp').config(['$provide', function ($provide) {
    $provide.decorator('$rootScope', ['$delegate', function ($delegate) {
        Object.defineProperty($delegate.constructor.prototype, 'timeout', {
            value: function (fn, number, invokeApply) {
                var $timeout = angular.injector(['ng']).get('$timeout'),
                    promise;
                promise = $timeout(fn, number, invokeApply);
                this.$on('$destroy', function () {
                    $timeout.cancel(promise);
                });
            },
            enumerable: false
        });
        return $delegate;
    }]);
}]);

但是我如何正确地进行单元测试呢?我觉得我应该做两个测试…1)检查当$rootScope.timeout()被调用时是否调用了原来的$timeout, 2)检查当作用域被销毁时是否取消了承诺。

这是我当前的测试套件:

describe('MyApp', function () {
    var $rootScope;
    beforeEach(function () {
        module('MyApp');
        inject(['$rootScope', function (_$rootScope_) {
            $rootScope = _$rootScope_;
        }]);
    });
    describe('$timeout', function () {
        it('<something>', function () {
            $rootScope.timeout(function () {}, 2500);
            // Test if the real $timeout was called with above parameters
            $rootScope.$destroy();
            // Test if the $timeout promise was destroyed
        });
    });
});

这唯一能做的就是给我100%的覆盖率。但那不是我想要的……我如何正确地测试它?

由于没有人能够帮助我,而我真的很想完成这件事,我最终找到了自己的解决方案。我不确定这是最好的解决方案,但我认为它确实有效。

我是这样解决的:

describe('MyApp', function () {
    var $rootScope,
        $timeout,
        deferred;
    beforeEach(function () {
        module('MyApp');
        inject(['$rootScope', '$q', function (_$rootScope_, _$q_) {
            $rootScope = _$rootScope_;
            deferred = _$q_.defer();
        }]);
        $timeout = jasmine.createSpy('$timeout', {
            cancel: jasmine.createSpy('$timeout.cancel')
        }).and.returnValue(deferred.promise);
        spyOn(angular, 'injector').and.returnValue({
            get: function () {
                return $timeout;
            }
        });
    });
    describe('$timeout', function () {
        it('should set the timeout with the specified arguments', function () {
            $rootScope.timeout(angular.noop, 250, false);
            expect($timeout).toHaveBeenCalledWith(angular.noop, 250, false);
        });
        it('should cancel the timeout on scope destroy event', function () {
            $rootScope.timeout(angular.noop, 250, false);
            $rootScope.$destroy();
            expect($timeout.cancel).toHaveBeenCalledWith(deferred.promise);
        });
    });
});

相关内容

  • 没有找到相关文章

最新更新