如何在AngularJS Karma单元测试中触发`$ on`事件?

Ben*_*old 6 unit-testing angularjs karma-runner

我试图$scope.$on()在我$rootScope.broadcast()发生事件时触发的控制器中触发该方法.我发现这个问题很有用:如何以角度测试事件?,但我仍然无法$rootScope通过控制器检测到从上方广播的事件$scope.

到目前为止,我已经设法测试该$broadcast方法是在相应的上调用的$rootScope,但并不是说该$on方法是在相应的$scope$broadcast调用的$rootScope.

我试图$rootScope.$broadcast直接进行测试,但是我的间谍没有接受这个事件.

这是我的控制器:

angular.module('app.admin.controllers.notes', [])
    .controller('NotesCtrl', function($scope) {

      $scope.$on('resource-loaded', function(event, resource) { // I want to test this
        $scope.parentType = resource.type;
        $scope.parentId = resource.id;
      });

    });
Run Code Online (Sandbox Code Playgroud)

这是我的测试:

describe('The notes controller', function() {

  beforeEach(module('app.admin.controllers.notes'));

  var scope, rootScope, NotesCtrl;

  beforeEach(inject(function($controller, $injector, $rootScope) {
    rootScope = $rootScope;
    scope = $rootScope.$new(); // I've tried this with and without $new()
    NotesCtrl = $controller('NotesCtrl', {$scope: scope}); // I've tried explicitly defining $rootScope here
  }));

  it('should respond to the `resource-loaded` event', function() {
    spyOn(scope, '$on');
    rootScope.$broadcast('resource-loaded'); // This is what I expect to trigger the `$on` method
    expect(scope.$on).toHaveBeenCalled();
  });

});
Run Code Online (Sandbox Code Playgroud)

是傻瓜.我已经包含了该$broadcast方法的通过测试以供参考,主要是因为我以相同的方式设置了测试.

我已经阅读了很多关于在AngularJS中测试事件的问题,它似乎总是一个范围问题.我在Karma单元测试中听说过,$rootScope并且$scope是一回事,但我不确定其含义是什么.我已经尝试定义$rootScope$scope作为相同的对象,以及在测试期间明确地注入,但没有任何东西使我的测试$rootScope变为NotesCtrl绿色.

如何$on在我的NotesCtrl测试中获取该方法?

JB *_*zet 11

是什么让它失效是因为你正在监视这个$on功能.不合理时它工作正常:http://plnkr.co/edit/hNEj7MmDDKJcJ7b298OB?p = info .原因很简单.当事件被brodcasted时,所谓的不是$on()函数.所谓的回调函数作为参数传递给$on()之前的:监听器.

请注意,通过监视$ on函数,您不会在此处测试代码.你要测试的是,当广播en事件时,子范围接收它.所以你正在测试AngularJS本身.

  • 这实际上是迟来的,但是为了将来找到这个的人参考,你可以在创建你的间谍时通过添加.and.callThrough()来测试这样的情况. (2认同)