angularjs路由unit testing

正如我们在http://docs.angularjs.org/tutorial/step_07中看到的,

angular.module('phonecat', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}). when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}). otherwise({redirectTo: '/phones'}); }]); 

build议使用e2etesting进行路由testing,

  it('should redirect index.html to index.html#/phones', function() { browser().navigateTo('../../app/index.html'); expect(browser().location().url()).toBe('/phones'); }); 

不过,我认为'$ routeProvider'configuration是使用单个函数($ routeProvider)完成的,我们应该能够在不涉及浏览器的情况下进行unit testing,因为我认为路由function不需要浏览器DOM。

例如,
当url是/ foo时,templateUrl必须是/partials/foo.html而控制器是FooCtrl
当url是/ bar时,templateUrl必须是/partials/bar.html,而控制器是BarCtrl

这是一个简单的IMO函数,它也应该在一个简单的testing中进行testing,一个unit testing。

我googlesearch这个$ routeProviderunit testing,但没有运气。

我想我可以从这里借用一些代码,但不能做到这一点, https://github.com/angular/angular.js/blob/master/test/ng/routeSpec.js 。

为什么不只是断言路由对象configuration正确?

 it('should map routes to controllers', function() { module('phonecat'); inject(function($route) { expect($route.routes['/phones'].controller).toBe('PhoneListCtrl'); expect($route.routes['/phones'].templateUrl). toEqual('partials/phone-list.html'); expect($route.routes['/phones/:phoneId'].templateUrl). toEqual('partials/phone-detail.html'); expect($route.routes['/phones/:phoneId'].controller). toEqual('PhoneDetailCtrl'); // otherwise redirect to expect($route.routes[null].redirectTo).toEqual('/phones') }); }); 

我想你应该能够像这样testing$ routeProvider:

 angular.module('phonecat', []). config(['$routeProvider', function($routeProvider) { $routeProvider. when('/phones', {templateUrl: 'partials/phone-list.html', controller: PhoneListCtrl}). when('/phones/:phoneId', {templateUrl: 'partials/phone-detail.html', controller: PhoneDetailCtrl}). otherwise({redirectTo: '/phones'}); }]); it('should test routeProvider', function() { module('phonecat'); inject(function($route, $location, $rootScope) { expect($route.current).toBeUndefined(); $location.path('/phones/1'); $rootScope.$digest(); expect($route.current.templateUrl).toBe('partials/phone-detail.html'); expect($route.current.controller).toBe(PhoneDetailCtrl); $location.path('/otherwise'); $rootScope.$digest(); expect($location.path()).toBe('/phones/'); expect($route.current.templateUrl).toEqual('partials/phone-list.html'); expect($route.current.controller).toBe(PhoneListCtrl); }); }); 

结合前面的两个答案,如果你想testing路由器作为一个黑盒子,它应该成功路由(不是控制器configuration自己),无论路由可能是什么:

 // assuming the usual inject beforeEach for $route etc. var expected = {}; it('should call the right controller for /phones route', function () { expected.controller = $route.routes['/phones'].controller; $location.path('/phones'); $rootScope.$digest(); expect($route.current.controller).toBe(expected.controller); }); it('should redirect to redirectUrl from any other route', function () { expected.path = $route.routes[null].redirectTo; $location.path('/wherever-wrong'); $rootScope.$digest(); expect($location.path()).toBe(expected.path); });