2013-05-23 19 views
5

Chcę przetestować zasoby angularjs.

'use strict'; 

/** 
* AddressService provides functionality to use address resource in easy way. 
* 
* This is an example usage of method: 
* 
* `get`: 
* 
    var a = AddressService.get({id: '1'}, 
     function (data) { 
      // Work here with your resource 
     } 
    ); 
* 
*/ 
App.factory('AddressService', function ($resource, $rootScope) { 
    var url = [ 
      $rootScope.GLOBALS.API_PATH, 
      $rootScope.GLOBALS.API_VERSION, 
      'models/address/:id' 
     ].join('/'), 

     actions = { 
      'get': { 
       method: 'GET', 
       params: {id: '@id'} 
      } 
     }; 
    return $resource(url, {}, actions); 
}); 

stworzyłem Test:

'use strict'; 

var $httpBackend; 

describe('Service: AddressService', function() { 

    beforeEach(module('myApp')); 

    beforeEach(inject(function ($injector) { 
     var url_get = 'api/v1/models/address/5'; 

     var response_get = { 
      address_line_1: '8 Austin House Netly Road', 
      address_line_2: 'Ilford IR2 7ND' 
     }; 

     $httpBackend = $injector.get('$httpBackend'); 

     $httpBackend.whenGET(url_get).respond(response_get); 

    })); 

    describe('AddressService get test', function() { 
     it('Tests get address', inject(function (AddressService) { 
      var address = AddressService.get({ id: '5'}); 
      $httpBackend.flush(); 
      expect(address.address_line_1).toEqual('8 Austin House Netly Road'); 
      expect(address.address_line_2).toEqual('Ilford IR2 7ND'); 
     })); 
    }); 
}); 

Nie mam doświadczenie z kątowy bardzo dobrze. Ustawiłem jaśmin w pliku karma.config.js. AngularJS v1.0.6 Projekt zarządzania Yoeman and Grunt.

staram grunt test

Running "karma:unit" (karma) task 
INFO [karma]: Karma server started at http://localhost:8080/ 
INFO [launcher]: Starting browser Chrome 
INFO [Chrome 27.0 (Linux)]: Connected on socket id RFFUY5bW8Hb5eTu0n-8L 
Chrome 27.0 (Linux) Service: AddressService AddressService get Tests get address FAILED 
     Error: Unexpected request: GET views/home.html 
     No more request expected 
      at Error (<anonymous>) 
      at $httpBackend (/home/bart/y/projects/x/frontend/app/components/angular-mocks/angular-mocks.js:910:9) 
      at sendReq (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:9087:9) 
      at $http (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:8878:17) 
      at Function.$http.(anonymous function) [as get] (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:9021:18) 
      at $q.when.then.then.next.locals (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:7394:34) 
      at wrappedCallback (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:6797:59) 
      at wrappedCallback (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:6797:59) 
      at /home/bart/y/projects/x/frontend/app/components/angular/angular.js:6834:26 
      at Object.Scope.$eval (/home/bart/y/projects/x/frontend/app/components/angular/angular.js:8011:28) 
     Error: Declaration Location 
      at window.jasmine.window.inject.angular.mock.inject (/home/bart/y/projects/x/frontend/app/components/angular-mocks/angular-mocks.js:1744:25) 
      at null.<anonymous> (/home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:32:30) 
      at null.<anonymous> (/home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:31:5) 
      at /home/bart/y/projects/x/frontend/test/spec/services/userdata/AddressService.js:5:1 
.................................................................. 
Chrome 27.0 (Linux): Executed 67 of 67 (1 FAILED) (0.343 secs/0.179 secs) 
Warning: Task "karma:unit" failed. Use --force to continue. 

Jeśli usunąć $httpBackend.flush() w teście. Test przechodzi. Ale otrzymuję undefined od address. Widziałem przykłady: example wszystko użyć flush() Ale tylko mam głupie wyjątek: Error: Unexpected request: GET views/home.html

views/home.html moim zdaniem w katalogu projektu. Nie mam pojęcia, jak rozwiązać mój problem, nie mogłem znaleźć żadnego rozwiązania. Czy w jakiś sposób tę kwestię brakuje?

Czy ktoś może zobaczyć błąd w moim kodzie? Wszystkie sugestie będą doceniane.

EDIT

znalazłem, że muszę to wykorzystać:

$httpBackend.when('GET', /\.html$/).passThrough(); 

Ale Innym problemem jest Dostaję:

TypeError: Object #<Object> has no method 'passThrough' 

Odpowiedz

8

I w końcu znaleźć rozwiązanie:

Próbowałem wykonać to: other post

Więc dodałem $templateCache:

'use strict'; 

var $httpBackend; 

describe('Service: AddressService', function() { 

    beforeEach(module('myApp')); 

    beforeEach(inject(function ($injector, $templateChache) { 
     $templateCache.put('views/home.html', '.<template-goes-here />'); 
     var url_get = 'api/v1/models/address/5'; 

     var response_get = { 
      address_line_1: '8 Austin House Netly Road', 
      address_line_2: 'Ilford IR2 7ND' 
     }; 

     $httpBackend = $injector.get('$httpBackend'); 

     $httpBackend.whenGET(url_get).respond(response_get); 

    })); 

    describe('AddressService get test', function() { 
     it('Tests get address', inject(function (AddressService) { 
      var address = AddressService.get({ id: '5'}); 
      $httpBackend.flush(); 
      expect(address.address_line_1).toEqual('8 Austin House Netly Road'); 
      expect(address.address_line_2).toEqual('Ilford IR2 7ND'); 
     })); 
    }); 
}); 
+2

Dlaczego szablon templateCache jest ważny?Wygląda na to, że nie ma to nic wspólnego z usługą API. –

+5

Zgadzam się. Wygląda to na okropny hack, by zignorować problem. Natrafiam teraz na te same problemy i nie jestem pewien, dlaczego tak się dzieje ... – Pwnna

+2

Są to testy jednostkowe i musisz wyodrębnić określone jednostki (w tym przypadku usługę), aby je przetestować. Usuń wszystkie inne zależności nawet z szablonów, które są po prostu wyśmiewane tutaj. Nie wiem, lepszy sposób to zrobić, nie mam pojęcia o rdzeniu przepływu. I to pytanie nie jest jeszcze zamknięte. –

4

błąd jest spowodowany testu próbuje załadować stronę główną dla swojej aplikacji. Ponieważ nie powiedzieli Państwo, że test oczekuje połączenia z serwerem, zwracany jest błąd. Więcej informacji na ten temat można znaleźć w dokumentacji dla $httpBackend.

Twój sposób obejścia $ templateCache został zaprojektowany dla dyrektyw dotyczących testowania jednostkowego, a nie innych czynności. Byliście bardzo blisko z:

$httpBackend.when('GET', /\.html$/).passThrough(); 

Ponieważ nie trzeba nic robić z rzeczywistą pliku szablonu jest to bezpieczny i prosty obejść dodać to do beforeEach() bloku.

$httpBackend.whenGET(/\.html$/).respond(''); 

Dzięki temu nie można uzyskać określonego błędu TypeError.

TypeError: Object #<Object> has no method 'passThrough' 

Miałem ten sam problem w moich testów jednostkowych po aktualizacji do nowej wersji kątowej JS i korzystania respond('') działało.

+1

Czy nie można w zamian uniknąć usługi $ http wysyłającej takie żądanie na główną stronę aplikacji? – Stephane

Powiązane problemy