我们能为 AngularJS 的 routeProvider 编写单元测试吗?

17

嗨,我正在使用AngularJS构建应用程序,并且我卡在了单元测试部分。我知道如何为控制器编写单元测试,但不知道如何为routeProvider编写测试。我正在使用Jasmine编写单元测试。

我的routeProvider代码如下:

    var app = angular.module('MyApp', ['ngResource'])

     app.config(function ($routeProvider) {
        $routeProvider
          .when('/', {
            templateUrl: 'app/views/main.html',
            controller: 'MainCtrl'
          })
          .when('/home/:PartyID', {
            templateUrl: 'app/views/home.html',
            controller: 'HomeCtrl'
          })
           .when('/edit/:PartyID', {
            templateUrl: 'app/views/update_profile.html',
            controller: 'EditCtrl'
          })
          .when('/route', {
            templateUrl: 'app/views/route.html',
            controller: 'RouteCtrl'
          })
          .when('/signup', {
            templateUrl: 'app/views/signup.html',
            controller: 'SignupCtrl'
          })
          .when('/login', {
            templateUrl: 'app/views/login.html',
            controller: 'LoginCtrl'
          })
          .otherwise({
            redirectTo: '/'
          });  
 });

我该如何使用Jasmine为这个routeProvider编写单元测试?


1
我猜你不想为routeProvider编写测试,而是想检查你的URL。这在教程http://docs.angularjs.org/tutorial/step_07中有介绍。 - Eduard Gamonal
所以您的意思是我不需要为routeProvider编写单元测试,而是编写端到端测试以检查URL是否正确。对吗? - BKM
是的,routeprovider是由Angular团队已经测试过的服务。你只需要使用一个实例来修改存储URL的对象即可。 - Eduard Gamonal
2
单元测试路由是完全合理的。意图不是测试即将过时的$routeProvider,而是测试url、template和controller之间的映射关系。这里是一个例子。 - zhon
2
“单元测试”是指测试代码单元的某些内部逻辑。你试图测试的是“配置”。这超出了所有你的“单元”,应该只在端到端测试中进行测试。 - hon2a
2个回答

23

可以的,这是一个快速的答案。下面是一小段代码,可以使用并扩展它来测试路由是否将您带到预期的位置。


是的,你可以。上面是一小段代码,可以用来测试路由是否会带你去你所期望的地方。
describe('Testing routes', function() {
    beforeEach(module('windscreens'));

    var location, route, rootScope;

    beforeEach(inject(
        function( _$location_, _$route_, _$rootScope_ ) {
            location = _$location_;
            route = _$route_;
            rootScope = _$rootScope_;
    }));

     describe('Login route', function() {
        beforeEach(inject(
            function($httpBackend) {
                $httpBackend.expectGET('login')
                .respond(200);
            }));

        it('should load the login page on successful load of /login', function() {
            location.path('/login');
            rootScope.$digest();
            expect(route.current.controller).toBe('LoginCtrl')
        });
    });    
});

1
嗨Nick,感谢您提供这个简单明了的示例。虽然对我来说,这更像是一种行为测试而不是单元测试。 - Greg Wang
嗯,@GregWang 你说得对。不过要注意,Jasmine更适合BDD而非TDD。 - Nick Lewis

15

保持简单

describe('Testing Routes', function () {

// load the controller's module
beforeEach(module('MyApp'));

it('should test routes',
inject(function ($route) {

  expect($route.routes['/'].controller).toBe('MainCtrl');
  expect($route.routes['/'].templateUrl).toEqual('app/views/main.html');

  expect($route.routes['/home/:PartyID'].controller).toBe('HomeCtrl');
  expect($route.routes['/home/:PartyID'].templateUrl).toEqual('app/views/home.html');

  expect($route.routes['/edit/:PartyID'].controller).toBe('EditCtrl');
  expect($route.routes['/edit/:PartyID'].templateUrl).toEqual('app/views/update_profile.html');

  expect($route.routes['/route'].controller).toBe('RouteCtrl');
  expect($route.routes['/route'].templateUrl).toEqual('app/views/route.html');

  expect($route.routes['/signup'].controller).toBe('SignupCtrl');
  expect($route.routes['/signup'].templateUrl).toEqual('app/views/signup.html');

  expect($route.routes['/streamconfigs/:id'].controller).toBe('LoginCtrl');
  expect($route.routes['/streamconfigs/:id'].templateUrl).toEqual('app/views/login.html');

  expect($route.routes[null].redirectTo).toEqual('/');
}));

});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接