如何用$ scope.$ on对单元测试Angular控制器?

MJV*_*MJV 13 unit-testing jasmine angularjs karma-runner

我的Angular应用程序中有一个带有事件监听器的控制器,定义如下.

  angular.module('test').controller('TestCtrl', function($rootScope, $scope, testService) {

    [...]

    $scope.$on("myEvent", function(args, value) {
      testService.doStuff(value);
    });
  });
Run Code Online (Sandbox Code Playgroud)

这在应用程序本身中完美运行.但是,当我尝试对控制器的功能进行单元测试时(使用JasmineKarma),每个测试方法都会抛出以下错误:

 TypeError: $scope.$on is not a function in [...]/testController.js
Run Code Online (Sandbox Code Playgroud)

我在我的测试方法中创建控制器如下.

  it('does stuff', inject(function($rootScope, $controller, testService) {
    var scope = $rootScope.$new;
    $controller('TestCtrl', {
      $scope : scope
    });

    [...]
  }));
Run Code Online (Sandbox Code Playgroud)

我可以通过改变我的控制器来解决这个问题rootScope:

  $rootScope.$on(...)
Run Code Online (Sandbox Code Playgroud)

但当然,应用程序不再按预期工作.我也可以通过$on在我的测试代码中引入该方法来消除错误:

  var scope = $rootScope.$new;
  scope.$on = function() {};
Run Code Online (Sandbox Code Playgroud)

但是像这样嘲笑听众会破坏测试我真实代码的目的.

为什么测试代码没有找到 $on 方法 scope(但发现它rootScope仍然......)

必须有一些我在这里缺少的基本功能,但即使经过大量的谷歌搜索和阅读Angular源代码,我也无法弄明白.

Mat*_*ork 16

$rootScope.$new是一个功能.你需要调用它($rootScope.$new()):

it('does stuff', inject(function($rootScope, $controller, testService) {
  var scope = $rootScope.$new();
  $controller('TestCtrl', {
    $scope : scope
  });

  [...]
}));
Run Code Online (Sandbox Code Playgroud)

示例插件:http://plnkr.co/edit/t1x62msmOQDkNItGzcp9?p = preview