2014-01-23 10 views
5

Ich schreibe einen Jasmin-Test für meine DetailCtrl. Ich habe 10 JSON-Datei mit jeweils Dateinamen wie diese

1.json 
2.json 
3.json 

in meinem Datenordner

Hier meine Details Ctrl

backpagecontrollers.controller('DetailCtrl', function($scope, $stateParams, $http) { 
    $http.get('data/' + $stateParams.listingId + '.json').success(function(data) { 
     $scope.extrainfo = data; 
    }); 
}); 
ist

Die Detail-Controller jedes 1.json abruft, 2. json, 3.json Datei aus meinem Datenordner.

Hier ist ein Teil meiner Route

ist
.state('listingdetail', { 
     url: "/listings/:listingId", 
     templateUrl: "partials/detail.html", 
     controller: 'DetailCtrl' 
    }) 

Ermöglicht mit dem Testkopf zurück, ich injiziert sowohl die $stateParams und die $state in den Test.

Ich möchte testen, dass für jede JSON-Datei oben die Bilder in meiner JSON-Datei existieren. Ich setze das httpbackend, um die lokale host url plus die listingId von der $stateparams zu erhalten, die ich als Teil der Routen konfigurierte, aber die listingId kommt als undefined zurück. Soll ich etwas anderes in meinen Test spritzen?

describe('Detail Ctrl', function() { 

     var scope, ctrl, httpBackend, stateparams, listingId; 

     beforeEach(angular.mock.module("backpageApp")); 
     beforeEach(angular.mock.inject(function($controller, $rootScope, _$httpBackend_, $stateParams, $state) { 
     httpBackend = _$httpBackend_; 
     stateparams = $stateParams; 
     listingId = stateparams.listingId; 

     httpBackend.expectGET('http://localhost:8000/#/listings/' + listingId).respond([{id: 1 }, {id: 2}, {id:3}, {id:4}, {id:5}, {id:6}, {id:7}, {id:8}, {id:9}, {id:10}]); 
     scope = $rootScope.$new(); 
     ctrl = $controller("DetailCtrl", {$scope:scope}); 
     })); 

     it('the images for each listing should exist', function() { 
     httpBackend.flush(); 
     expect(scope.images).toBe(true) 
     }); 
    }); 

Ich erhalte diesen Fehler

Error: Unexpected request: GET data/undefined.json 
    Expected GET http://localhost:8000/#/listings/undefined 

Antwort

28

Ich glaube, Sie könnten Missverständnisse, wie der Router mit dem Controller funktioniert. Wenn Sie einen Controller in der Unit testen, führen Sie keine Route aus oder geben Sie keinen UI-Router-Status ein. Diese Zustände und Routen sind Trigger-Controller, die ausgeführt werden, wenn die Anwendung normal ausgeführt wird. In einem Komponententest führen Sie den Controller jedoch explizit mit $ controller aus. Sie überspringen also den Routing-Teil insgesamt. Was bedeutet, dass Sie das Objekt, das der UI-Router normalerweise für Sie erstellen würde, verspotten sollten, $ stateparams.

describe('Detail Ctrl', function() { 

    var scope, ctrl, httpBackend, stateparams, listingId; 

    beforeEach(angular.mock.module("backpageApp")); 
    //don't need to inject state or stateparams here 
    beforeEach(angular.mock.inject(function($controller, $rootScope, _$httpBackend_) { 
    httpBackend = _$httpBackend_; 
    stateparams = { listingId: 1 }; //mock your stateparams object with your id 

    //you should be expecting the get request url from the controller, not the route 
    httpBackend.expectGET('data/' + stateparams.listingId + '.json').respond([{id: 1 }, {id: 2}, {id:3}, {id:4}, {id:5}, {id:6}, {id:7}, {id:8}, {id:9}, {id:10}]); 
    scope = $rootScope.$new(); 
    //pass your mock stateparams object to the controller 
    ctrl = $controller("DetailCtrl", {$scope:scope, $stateParams:stateparams}); 
    })); 

    it('the images for each listing should exist', function() { 
    httpBackend.flush(); 
    //I don't see images set in your controller, but you 
    //could check scope.extrainfo here 
    expect(scope.images).toBe(true) 
    }); 
}); 
+0

Können Sie mich auf einige Online-Tutorials verweisen, die das mehr erklären? Die Docs/Blogs sind bei Google nicht so gut. – Jngai1297

+0

Dieser ist ziemlich gut, denke ich: http://nathanleclaire.com/blog/2013/12/13/how-to-unit-test-controllers-in-angularjs-without-setting-your-hair-on-fire/ – JeffB

+0

Gah Ich überlege es immer wenn es so einfach ist. –

Verwandte Themen