所以我在应用程序配置中有这样的装饰器:
angular.module('app').config(['$provide', function ($provide) {
$provide.decorator('$rootScope', ['$delegate', function ($delegate) {
$delegate.constructor.prototype.$onRootScope = function (name, listener) {
var unsubscribe = $delegate.$on(name, listener);
this.$on('$destroy', unsubscribe);
};
$delegate.constructor.prototype.$watchRootScope = function (name, listener) {
var unsubscribe = $delegate.$watch(name, listener);
this.$on('$destroy', unsubscribe);
};
$delegate.constructor.prototype.$watchAfterLoad = function (watchExpression, listener, objectEquality) {
var initialLoad = true;
this.$watch(watchExpression, function () {
if (initialLoad) {
// note: this obviously runs outside of angular, so sometimes the timeout could run after initial load
setTimeout(function () { initialLoad = false; }, 25);
} else {
listener.apply(this, arguments);
}
}, objectEquality);
};
return $delegate;
}]);
}]);
正如你所看到的,这个装饰器让我使用 $scope.$onRootScope 而不是 $rootScope.$on 并负责在作用域销毁事件上自动删除监听器...
当我对包含 $scope.$onRootScope 的逻辑的代码进行单元测试时,我收到这样的错误: TypeError: undefined is not a constructor (evaluating 'scope.$onRootScope') in
在每次测试之前,我都会加载所有必需的模型并进行注入(inject),如下所示〜:
beforeEach(function () {
inject(function (_$rootScope_) {
$rootScope = _$rootScope_;
});
});
我该如何克服这个问题? 有没有办法模拟/模仿 $scope.$onRootScope 行为?
我对单元测试和 Jasmine 很陌生,很抱歉问题格式不太好。
编辑#1:
当我在将 $scope 对象(var $scope = {...})作为参数传递给我正在测试的服务方法之前模拟它时,我可以通过简单地定义 $scope 方法来避免错误:
$scope = {
...
$onRootScope: function() {}
}
仍在等待一些更好的想法:-)
最佳答案
我相信您需要基于修饰的 $rootScope
构建您的 $scope
,而不是创建一个新的虚拟对象。
像这样:
var $root, $scope;
beforeEach(function () {
module('app');
inject(function ($rootScope) {
$root = $rootScope;
$scope = $root.$new();
});
});
it('should have the expected property', function () {
expect($scope.constructor.prototype).to.have.property('$watchRootScope');
});
我将插入一个指向 spec suite 的链接我前段时间整理的一个迷你库,做的事情与你现在的情况大致相同。
关于javascript - 如何使用 Jasmine (Angular js) 对自定义装饰器进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31313554/