Jasmine unit test case for $routeChangeStart in AngularJS

两盒软妹~` 提交于 2019-12-10 15:24:08

问题


Hi I am building an app using AngularJS and now I am on to the unit testing my application. I know how to write unit test cases for services, controllers etc. But I don't know to write it for $routeChangeStart.

I have following code in my 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');
        }
    });
});

I have written this code to find out whether the user is logged in or not for each routing in my app. I have written a service AuthenticationService for this purpose like;

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

And my session service like;

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

I am using Jasmine to write test cases and using Istanbul for code coverage. When I run my test using Grunt I am getting something like this in my app.js;

It's because I am not covering these statements in my test cases as I don't know how to write test case for this particular piece of code. Any suggestions?


回答1:


That run block runs every time the module is loaded, so that listener is being registered during the tests. You just need that event to actually be sent so that you can test the code within it. Something like this should do the trick:

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

See How can I test events in angular? for how to test events in general.




回答2:


A good way to test $rootScope.$on('$routeChangeStart',... may be found in the unit tests of angularjs itself. It is an excellent source of knowledge as every feature is tested, so it's possible to find good solutions. That's why unit test is so great, isn't it ?

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

The following test (taken from angular head 1.2.x - follow the link for latest) works great, you just have to adapt to your test (as the event handler is already in your code):

'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);
    });
  });


来源:https://stackoverflow.com/questions/19093010/jasmine-unit-test-case-for-routechangestart-in-angularjs

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!