2017-05-31 53 views
0

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

测试

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(); 
    }); 
}); 

正如你可以看到上面的测试中创造了控制器没有做任何事情,但catch错误的。

这是一个模拟了在控制器代码:

代码

(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 
[email protected]/app/vendor<line number> 

并通过角堆栈跟踪和回测试。

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

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上,当它在主应用程序中?

+0

这现在造成了必须清理听众的问题! – Pureferret

回答

0

问题来自$on关心$parent这一事实。

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

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

这样,它将有所有属性angularjs希望它有,当$on叫做:

相反,用实例化。

相关问题