2013-04-13 11 views
40

jak widzimy tutaj http://docs.angularjs.org/tutorial/step_07,angularjs testowania jednostka trasa

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

Test routingu je do zrobienia z testu e2e,

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

Myślę jednak, że config w '$ routeProvider' jest wykonywane za pomocą jednej funkcji, funkcji ($ routeProvider), i powinniśmy być w stanie testować jednostkę bez angażowania przeglądarki, ponieważ myślę, że funkcja routingu nie wymaga przeglądarki DOM.

Na przykład
gdy URL jest/foo, templateUrl musi być /partials/foo.html i kontroler jest FooCtrl
gdy URL jest/bar, templateUrl musi być /partials/bar.html i kontroler jest BarCtrl

Jest to prosta funkcja IMO, a także powinna być testowana w prostym teście, jednostkowym teście.

Przeszukałem i szukałem tego testu jednostki $ routeProvider, ale bez powodzenia.

Myślę, że mogę pożyczyć kod z tego miejsca, ale nie mogłem go jeszcze uzyskać, https://github.com/angular/angular.js/blob/master/test/ng/routeSpec.js.

+0

jest jednym z dwóch wystarczająco dobrych? – Maarten

+0

Trzeba się zastanowić, czy dałoby to test jednostkowy, który zapewnia rzeczywistą wartość; większość konfiguracji trasy jest właśnie taka, konfiguracja, a test jednostkowy sprowadza się do "Is/some/route to/some/route?" – fwielstra

+1

@ fwielstra, Tak, ten rodzaj testu wydaje się być [podwójnym wpisem] (http://en.wikipedia.org/wiki/Double-entry_bookkeeping_system). Z drugiej strony uważam, że większość testów czuje się w ten sposób. Z drugiej strony uważam, że podwójne wejście jest użyteczne. – zhon

Odpowiedz

62

Dlaczego po prostu nie dochodzić przedmiotem trasa jest prawidłowo skonfigurowany?

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

Kiedy próbuję przetestować router, otrzymuję "nieokreślony" nie jest obiektem (oceniającym "$ route.routes [null] .redirectTo") "dla ostatniego scenariusza" oczekiwać ($ route.routes [null]. redirectTo) .toEqual ('/ phones') " – Brune

+13

To wygląda na całkiem bezużyteczny test dla mnie. Nie znaczy to, że styl zaproponowany przez innych jest lepszy. –

+2

Nie będzie to testowane, jeśli oparte na stanach trasy są dostępne/callabe. Na przykład, w jaki sposób obejmuje to przypadek "Nie jestem zalogowany i próbuję uzyskać dostęp do ograniczonego zasobu"? –

45

Myślę, że powinieneś być w stanie przetestować $ routeProvider tak:

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

    }); 
}); 
+2

To jest idealne. '$ rootScope. $ digest()' było dokładnie tym, czego potrzebowałem. – marcoseu

+0

ten test już nie działa ... – wakandan

+1

To nie działa, ponieważ Angular chce wywołać wywołanie HttpBackend, aby pobrać szablon przez Ajax ... rozwiązanie powyżej tego (z zhon) działa! – alchemication

4

Połączenie dwóch poprzednich odpowiedzi, jeśli chcesz przetestować router jako czarną skrzynkę, która z powodzeniem routingu, gdzie powinny (nie configs kontroler ETS w siebie), niezależnie od trasy mogą być:

// 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); 
}); 
Powiązane problemy