Подтвердить что ты не робот

Как unit test Angular контроллер с $scope. $On?

У меня есть контроллер с прослушивателем событий в моем приложении Angular, который определяется следующим образом.

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

    [...]

    $scope.$on("myEvent", function(args, value) {
      testService.doStuff(value);
    });
  });

Это прекрасно работает в самом приложении. Однако, когда я пытаюсь использовать unit test функциональность контроллера (используя Jasmine и Karma), каждый тестовый метод вызывает следующую ошибку:

 TypeError: $scope.$on is not a function in [...]/testController.js

Я создаю контроллер в своих методах тестирования следующим образом.

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

    [...]
  }));

Я могу обойти проблему, изменив мой контроллер, чтобы вместо этого использовать rootScope:

  $rootScope.$on(...)

но тогда, конечно, приложение больше не работает, как ожидалось. Я также могу избавиться от ошибки, введя метод $on в свой тестовый код:

  var scope = $rootScope.$new;
  scope.$on = function() {};

но издеваясь над слушателем, как этот вид поражений, цель тестирования моего реального кода.

Почему тестовый код не находит $on метод scope ? (но находит его на rootScope, все еще...)

Должно быть что-то фундаментальное, что мне здесь не хватает, но я не смог понять его даже после многого поиска и чтения исходного кода Angular.

4b9b3361

Ответ 1

$rootScope.$new - это функция. Вам нужно вызвать его ($rootScope.$new()):

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

  [...]
}));

Пример plunk: http://plnkr.co/edit/t1x62msmOQDkNItGzcp9?p=preview