【问题标题】:Jasmine unit test case for $routeChangeStart in AngularJSAngularJS 中 $routeChangeStart 的 Jasmine 单元测试用例
【发布时间】:2013-10-06 05:52:39
【问题描述】:

您好,我正在使用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 中出现了类似的内容;

这是因为我没有在我的测试用例中涵盖这些语句,因为我不知道如何为这段特定的代码编写测试用例。有什么建议吗?

【问题讨论】:

  • 您的应用中是否定义了任何路由?

标签: angularjs jasmine istanbul


【解决方案1】:

每次加载模块时都会运行 run 块,以便在测试期间注册监听器。您只需要实际发送该事件,以便您可以测试其中的代码。像这样的东西应该可以解决问题:

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

请参阅How can I test events in angular?,了解如何测试事件的一般性。

【讨论】:

    【解决方案2】:

    测试$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);
        });
      });
    

    【讨论】:

      猜你喜欢
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      • 2016-02-12
      • 1970-01-01
      • 1970-01-01
      • 2014-01-11
      • 1970-01-01
      • 2017-10-07
      相关资源
      最近更新 更多