Как я могу протестировать событие $ scope. $ в тесте Jasmine?

#angularjs #unit-testing #jasmine

#angularjs #модульное тестирование #jasmine

Вопрос:

Я тестирую контроллер и хочу протестировать обработчик событий. Скажем, мой контроллер выглядит так:

 myModule.controller('MasterController', ['$scope', function($scope){
    $scope.$on('$locationChangeSuccess', function() {
        $scope.success = true;
    });
}]);
  

Буду ли я транслировать это в своем тесте Jasmine? Выдал бы я его? Существует ли принятый стандарт?

Комментарии:

1. Вы пробовали мое решение?

2. Как вы в итоге протестировали это, @MailmanOdd?

3. Я только что добавил / принял свое решение, надеюсь, это поможет.

Ответ №1:

Решение, которое я придумал, заключается в следующем:

 describe('MasterController', function() {
    var $scope, $rootScope, controller, CreateTarget;

    beforeEach(function() {
        inject(function($injector) {
            $rootScope = $injector.get('$rootScope');
            $scope = $rootScope.$new();

            var $controller = $injector.get('$controller');

            CreateTarget = function() {
                $controller('MasterController', {$scope: $scope});
            }
        });
    });

    describe('$locationChangeSuccess', function() {
        it('should set $scope.success to true', function() {
            controller = CreateTarget();
            $rootScope.$broadcast('$locationChangeSuccess');
            expect($scope.success).toBe(true);
        });
    });
});
  

Комментарии:

1. Я в замешательстве, но разве это не то, что я ответил?

2. Это похоже, но вызов $scope. $digest был ненужным. На самом деле в моем приложении (отличном от этого упрощенного вопроса) это действительно вызывало проблемы. Кроме того, я считаю, что решил проблему до того, как увидел ваш пост, и больше никогда не проверял вопрос — извините!

Ответ №2:

Я не думаю, что существует «принятый стандарт», но в соответствии с исходным кодом $location событие транслируется, поэтому я бы высмеял это поведение и протестировал его таким образом:

 'use strict';

describe('MasterController', function() {
  var MasterController,
      $rootScope,
      $scope;

  beforeEach(module('myModule'));

  beforeEach(inject(function($rootScope, $injector, $controller) {
    $rootScope = $rootScope;
    $scope = $rootScope.$new();
    MasterController = $controller('MasterController', {
      '$scope': $scope
    });
    $scope.$digest();
  }));

  describe('$locationChangeSuccess event listener', function() {
    it('should set $scope.success to true', function() {
      var newUrl = 'http://foourl.com';
      var oldUrl = 'http://barurl.com'

      $scope.$apply(function() {
        $rootScope.$broadcast('$locationChangeSuccess', newUrl, oldUrl);
      });

      expect($scope.success).toBe(true);
    });
  });
});