Angular.js单元测试中$ scope的函数没有$,但是在test

时间:2017-05-31 10:45:02

标签: javascript angularjs jasmine karma-runner

我试图运行一个简单的单元测试,只是创建一个控制器(一位同事写了它,所以其他人可以添加他们自己的单元测试),但是我所做的改变甚至停止了传递。这位同事不知道为什么它不起作用。这是一个简单的测试。

测试

describe("My Controller", function () {
    var $q, $controller, $scope, $rootScope;
    var createCtrl;
    beforeEach(function () {
        module('myModule');
    });
    beforeEach(inject(function (_$q_, _$rootScope_, _$controller_, _$httpBackend_) {
        $controller = _$controller_;
        $scope = _$rootScope_.$new();
        $scope.$parent = {
            dummyFn: function() {}
        };
        createCtrl = function createCtrl() {
            return $controller('MyController', {
                '$q': _$q_,
                '$scope': $scope
            });
        };
    }));
}));
describe("Controller stability", function() {
    it("should initialise the controller without error", function() {
        var controller = createCtrl();
    });
});

正如您所看到的,上述测试并没有做任何事情,只是在创建控制器时遇到错误。

这是模拟控制器中的代码:

代码

(function() {
    "use strict";
     const {angular} = window;
     angular.module('myModule', [])
     .controller('MyController', MyController);
     MyController.$inject = ['$routeParams', '$scope'];
     function MyController($routeParams, $scope) {
         var vm = this;
         $scope.$on('event-name', function(event, eventData) {
             vm.eventData = eventData;
             updateData();
         })
     }
})();

我得到的错误取决于我如何经营业力,但看起来却松散相关。

如果我在命令行中运行gulp任务,我就明白了:

TypeError: undefined is not an object (evaluating 'current.$$listenerCount[name]') in dist/app/vendor.js
$on@dist/app/vendor<line number>

堆叠跟踪角度并返回测试。

如果我在Karma的调试窗口中运行它:

Uncaught TypeError: Cannot read property 'event-name' of undefined
at Scope.$get.Scope.$on (hostname.com:9876/base/dist/vendor.js:<line number>)

然后通过堆栈跟踪再次下降。

查看$on的代码,我无法理解为什么它会以这两种不同的方式失败。

更改控制器代码以使用$rootScope.$on似乎可以缓解测试,但我不明白测试需要的原因,而不是主应用程序。

为什么$on在测试中不在$scope上,当它在主应用中时?

1 个答案:

答案 0 :(得分:0)

问题来自$on关心$parent

的事实

它将检查父级并尝试查看是否存在另一个侦听器,但由于父级未正确创建,因此无法找到并死亡。

相反,用:

实例化它
$scope.$parent = angular.extend(_$rootScope_.$new(), {
        dummyFn: function() {}
});

这样,当调用$on时,它将具有angularjs期望它具有的所有属性。