Модульный тест Jasmine для $routeChangeStart в AngularJS

Привет, я создаю приложение, используя AngularJS, и теперь я приступаю к модульному тестированию своего приложения. Я знаю, как писать модульные тесты для сервисов, контроллеров и т. д. Но я не знаю, как написать это для $routeChangeStart.

У меня есть следующий код в моем app.js

app.run(function ($rootScope, $location, AuthenticationService) {
    $rootScope.$on('$routeChangeStart', function () {
        if (AuthenticationService.isLoggedIn()) {
            $rootScope.Authenticated = 'true';
            $rootScope.Identity = localStorage.getItem('identification_id');
        } else {
            $rootScope.Authenticated = 'false';
            $rootScope.Identity = localStorage.removeItem('identification_id');
        }
    });
});

Я написал этот код, чтобы узнать, вошел ли пользователь в систему или нет для каждой маршрутизации в моем приложении. Я написал службу AuthenticationService для этой цели, например;

app.factory('AuthenticationService', function (SessionService) {
    return {
        isLoggedIn: function () {
            return SessionService.get('session_id');
        }
    };
});

И мой сеансовый сервис нравится;

app.factory('SessionService', function () {
    return {
        get: function (key) {
            return localStorage.getItem(key);
        }
    };
});

Я использую Jasmine для написания тестовых случаев и использую Istanbul для покрытия кода. Когда я запускаю свой тест с помощью Grunt, я получаю что-то подобное в своем app.js;

введите здесь описание изображения

Это потому, что я не рассматриваю эти утверждения в своих тестовых примерах, поскольку я не знаю, как написать тестовый пример для этого конкретного фрагмента кода. Какие-либо предложения?


person BKM    schedule 30.09.2013    source источник
comment
У вас есть какой-либо маршрут, определенный в вашем приложении?   -  person Ye Liu    schedule 30.09.2013


Ответы (2)


Этот блок run запускается каждый раз при загрузке модуля, поэтому слушатель регистрируется во время тестов. Вам просто нужно, чтобы это событие действительно было отправлено, чтобы вы могли протестировать код внутри него. Что-то вроде этого должно помочь:

it("should test the $routeChangeStart listener", inject(function($rootScope) {
   $rootScope.$broadcast("$routeChangeStart");
   //expects for the listener
}));

См. Как проверить события в angular? как тестировать события в целом.

person dnc253    schedule 30.09.2013

Хороший способ проверить $rootScope.$on('$routeChangeStart',... можно найти в модульных тестах самого angularjs. Это отличный источник знаний, так как каждая функция тестируется, поэтому можно найти хорошие решения. Вот почему юнит-тесты так хороши, не так ли?

https://github.com/angular/angular.js/blob/master/test/ngRoute/routeSpec.js

Следующий тест (взято из angular head 1.2.x - перейдите по ссылке для получения последней версии) отлично работает, вам просто нужно адаптироваться к вашему тесту (поскольку обработчик событий уже находится в вашем коде):

'use strict';

describe('$route', function() {
  var $httpBackend;

  beforeEach(module('ngRoute'));

  beforeEach(module(function() {
    return function(_$httpBackend_) {
      $httpBackend = _$httpBackend_;
      $httpBackend.when('GET', 'Chapter.html').respond('chapter');
      $httpBackend.when('GET', 'test.html').respond('test');
      $httpBackend.when('GET', 'foo.html').respond('foo');
      $httpBackend.when('GET', 'baz.html').respond('baz');
      $httpBackend.when('GET', 'bar.html').respond('bar');
      $httpBackend.when('GET', 'http://example.com/trusted-template.html').respond('cross domain trusted template');
      $httpBackend.when('GET', '404.html').respond('not found');
    };
  }));

  it('should route and fire change event', function() {
    var log = '',
        lastRoute,
        nextRoute;

    module(function($routeProvider) {
      $routeProvider.when('/Book/:book/Chapter/:chapter',
          {controller: angular.noop, templateUrl: 'Chapter.html'});
      $routeProvider.when('/Blank', {});
    });
    inject(function($route, $location, $rootScope) {
      $rootScope.$on('$routeChangeStart', function(event, next, current) {
        log += 'before();';
        expect(current).toBe($route.current);
        lastRoute = current;
        nextRoute = next;
      });
      $rootScope.$on('$routeChangeSuccess', function(event, current, last) {
        log += 'after();';
        expect(current).toBe($route.current);
        expect(lastRoute).toBe(last);
        expect(nextRoute).toBe(current);
      });

      $location.path('/Book/Moby/Chapter/Intro').search('p=123');
      $rootScope.$digest();
      $httpBackend.flush();
      expect(log).toEqual('before();after();');
      expect($route.current.params).toEqual({book:'Moby', chapter:'Intro', p:'123'});

      log = '';
      $location.path('/Blank').search('ignore');
      $rootScope.$digest();
      expect(log).toEqual('before();after();');
      expect($route.current.params).toEqual({ignore:true});

      log = '';
      $location.path('/NONE');
      $rootScope.$digest();
      expect(log).toEqual('before();after();');
      expect($route.current).toEqual(null);
    });
  });
person unludo    schedule 26.02.2014