2013-05-23 3 views
5

Ich möchte angularjs Ressource testen.

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

Ich habe den 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'); 
     })); 
    }); 
}); 

Ich bin nicht sehr gut mit Winkel erlebt. Ich habe Jasmin in karma.config.js gesetzt. AngularJS v1.0.6 Yoeman und Grunt verwalten Projekt.

Ich versuche 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. 

Wenn ich $httpBackend.flush() in Test entfernen. Der Test ist vorüber. Aber ich bekomme undefined von address. Ich sah Beispiele: example alle flush() verwenden aber nur ich dumme Ausnahme: Error: Unexpected request: GET views/home.html

views/home.html ist meiner Ansicht nach in Projektverzeichnis. Ich habe keine Ahnung, wie ich mein Problem lösen könnte. Ich konnte keine Lösung finden. Verpasse ich den Punkt irgendwie?

Kann jemand Fehler in meinem Code sehen? Alle Vorschläge werden zu schätzen wissen.

EDIT

Ich habe festgestellt, dass ich dies verwenden müssen:

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

Aber ein anderes Problem ist, ich bin immer:

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

Antwort

8

ich endlich gefunden Lösung haben:

Ich habe versucht, dies zu folgen: other post

So

Ich habe $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

Warum ist der templateCache wichtig?Es scheint, dass es nichts mit einem API-Service zu tun hat. –

+5

Ich stimme zu. Dies scheint ein schrecklicher Hack zu sein, um das Problem zu ignorieren. Ich stoße jetzt auf die gleichen Probleme und ich bin nicht sicher, warum dies der Fall ist ... – Pwnna

+2

Dies sind Komponententests und Sie müssen bestimmte Einheiten (Service in diesem Fall) zum Testen extrahieren. Entferne alle anderen Abhängigkeiten, auch Templates, die hier einfach abgespottet werden. Ich kenne keinen besseren Weg, um es zu tun, habe auch keine Ahnung vom Kernwinkelfluss. Und diese Frage ist noch nicht geschlossen. –

4

der Fehler durch den Test verursacht, das versucht, die Haupt-Seite für Ihre App zu laden. Da Sie dem Test nicht mitgeteilt haben, dass dieser Serveraufruf erwartet wird, wird ein Fehler zurückgegeben. Weitere Informationen hierzu finden Sie in der Dokumentation für $httpBackend.

Ihre $ templateCache-Problemumgehung wurde für Unit-Testing-Direktiven entwickelt, nicht für andere Zwecke. Sie waren ganz in der Nähe mit:

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

Da Sie nichts mit der eigentlichen Vorlagendatei tun müssen, um es um eine sichere und einfache Arbeit ist das zu Ihrem before() Block hinzuzufügen.

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

Dies stoppt Sie erhalten die TypeError Sie hatten.

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

Ich hatte das gleiche Problem in meinen Unit-Tests nach auf eine neue Version von Angular JS Upgrade und mit respond('') haben gut funktioniert.

+1

Ist es nicht möglich, stattdessen zu vermeiden, dass der $ http-Dienst eine solche Anfrage an die Hauptseite der Anwendung sendet? – Stephane