angularjs route unit testing
Solution 1
Why not just assert the route object is configured correctly?
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')
});
});
Solution 2
I think you should be able to test the $routeProvider like this:
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);
});
});
Solution 3
Combining the two previous answers, if you want to test the router as a black box that is successfully routing where it should (not the controller ets configs in themselves), whatever the routes might be:
// 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);
});
![allenhwkim](https://i.stack.imgur.com/d7RlD.png?s=256&g=1)
allenhwkim
less code, less maintenance LinkedIn: https://ca.linkedin.com/in/allenhwkim Github: https://github.com/allenhwkim The best programming is, no programming
Updated on July 20, 2022Comments
-
allenhwkim almost 2 years
As we see here in 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'}); }]);
routing test is suggested to be done with e2e test,
it('should redirect index.html to index.html#/phones', function() { browser().navigateTo('../../app/index.html'); expect(browser().location().url()).toBe('/phones'); });
However, I think the '$routeProvider' config is done with a single function, function($routeProvider), and we should be able to unit test without involvement of browser since I think routing function does not require browser DOM.
For example,
when url is /foo, templateUrl must be /partials/foo.html and controller is FooCtrl
when url is /bar, templateUrl must be /partials/bar.html and controller is BarCtrlIt is a simple function IMO, and it should also be tested in a simple test, a unit test.
I googled and searched for this $routeProvider unit test, but no luck yet.
I think I may borrow some code from here but couldn't make it yet, https://github.com/angular/angular.js/blob/master/test/ng/routeSpec.js.
-
marcoseu about 11 yearsThis is perfect.
$rootScope.$digest()
was exactly what I needed. -
alchemication over 10 yearsThis does not work as Angular wants to trigger a HttpBackend call to retrieve the template through Ajax... solution above this one (from zhon) works though!
-
ghiden over 10 yearsJust need to add $httpBackend with proper expectGET. Here is my example plnkr.co/edit/j1o0iu?p=preview
-
Olivier Amblet about 10 yearsI think this solution is better as it can test route parameter resolution as well. instead of using $httpBackend, you can load your template using something like: beforeEach(module('partials/browse-view.html'));
-
Brune almost 10 yearsWhen i try to test the router i'm getting "'undefined' is not an object (evaluating '$route.routes[null].redirectTo')" for the last scenario "expect($route.routes[null].redirectTo).toEqual('/phones')"
-
Duarte Cunha Leão almost 10 yearsThis looks like a pretty useless test to me. Not to say the style proposed by others is better.
-
Andresch Serj over 9 yearsThis won't test if based on states routes are available/callabe. For instance, how does this cover the case "I am not logged in and try to access a restricted recource"?
-
zhon over 7 years@AndreschSerj, the OP asked how do I unit test routes. Your comment would make a great system test.