javascript - 如何使用 Jasmine (Angular js) 对自定义装饰器进行单元测试

标签 javascript angularjs unit-testing jasmine

所以我在应用程序配置中有这样的装饰器:

    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/

相关文章:

javascript - Websocket 服务器在多人游戏中存在大量延迟

javascript - AngularJS 中的嵌套模块

angularjs - 在 Firebase 上重新加载 Angular 页面时找不到页面

c# - 如何运行 TestClass 的所有单元测试及其内部 TestClass 测试?

javascript - 如何键入组件的样式属性以接受数组?

javascript - 为什么 __proto__ 周围的方括号使其在对象中可枚举

jquery - 网址验证。 ng 模式不起作用

c++ - 微软 Visual Studio : How to keep the console open without manually reading input?

c# - ConfigurationManager.AppSettings 在单元测试项目中返回 Null

javascript - 在 JQuery 中执行 JavaScript .replace