2016-07-22 22 views
0

Ich versuche, einen Controller zu testen. Der Controller verwendet einen Dienst, der $ http verwendet, um die Daten aus einer JSON-Datei abzurufen (Diese JSON-Datei ist nur ein Mock-up der vom Server zurückgegebenen Antwort)

Mein Problem ist, dass wenn ich den Controller teste, er erstellt das Controller-Objekt und ruft sogar den Service auf. Aber es ruft nicht die verspottete $ HTTP-Antwort auf. Ich bin mir nicht sicher, wo ich falsch liege. Ich habe versucht, einige Beispiele zu betrachten, aber alle benutzen $ q.

Mein Service sieht wie folgt aus:

(function(){ 
    angular.module('mymodule') 
    .factory('MyService', MyService); 
    MyService.$inject = ['$http']; 

    function MyService($http) { 

    var service = { 
     retrieveData : retrieveData 
    }; 
    return service; 

    function retrieveData(containerLabel){ 
     var myGrossData = []; 
     var isMatchFound = false; 
     var myindex = containerLabel.slice(-4); 

     return $http.get('app/myGrossData.json').then(function(response) { 
      console.log('inside http retrieveData: '); 
      myGrossData = response.data; 
      var myindexExists = false; 

      var mydataObject = []; 
      var defaultdata = []; 
      angular.forEach(myGrossData, function (myGrossData) { 
      if (myindex === myGrossData.myindex) { 
       mydataObject = myGrossData; 
       isMatchFound = true; 
      } 

      if(!isMatchFound && myGrossData.myindex === '2006') 
      { 
       mydataObject = myGrossData; 
      } 

      if(myGrossData.myindex === '2006'){ 
       defaultdata = myGrossData; 
      } 
      }); 
      if (isMatchFound && response.status === 200) 
      { 
      return mydataObject; 
      } 

      else if(!isMatchFound && (response.status === 200 || response.status === 201)){ 
      return defaultdata; 
      } 

      else //all other responses for success block 
      { 
      return 'Incorrect Response status: '+response.status; 
      } 
     }, 
     function(error){ 
      return 'Error Response: '+error.status; 
     } 
    ); 
    } 
    }; 
})(); 

Der Controller ruft es ist:

(function() { 
    'use strict'; 
    angular 
    .module('mymodule', []) 
    .controller('MyCtrl', MyCtrl); 

    MyCtrl.$inject = ['$scope', 'MyService']; 

    function MyCtrl($scope, MyService) { 
    var vm = this; 
    vm.datafromsomewhere = datafromsomewhere; 
    vm.displayData = []; 
    vm.disableBarCode = false; 
    vm.childCount = 0; 
    vm.headertext="Master Container Builder"; 

    init(); 

    function init() { 
     console.log('MyCtrl has been initialized!'); 
     console.log(vm.headertext); 
    } 

    function myfunctionCalledByUI(input) { 
     processData(input); 
    } 

    function processData(containerLabel){  
     MyService.retrieveMasterContainer(containerLabel).then(function(data){ 
     vm.displayData = data; 
     }); 

     vm.disableBarCode = true; 
     vm.childCount = (vm.displayData.childData === undefined) ? 0: vm.displayData.childData.length; 
     vm.headertext="Myindex "+vm.displayData.myindex; 

     if (vm.displayData.masterDataId.match(/[a-z]/i)) { 
     // Validation passed 
     vm.displayData.masterDataId ="No Shipping Label Assigned"; 
     } 
     else 
     console.log('else: '+vm.displayData.masterDataId); 
     console.log('length of childData: '+vm.childCount); 
    } 
    } 
})(); 

und schließlich wie dies meine spec aussieht:

var expect = chai.expect; 

describe('Test Controller', function() { 

    var rootScope, compile; MyService = {}; 
    var $scope, $controller; 
    beforeEach(module('ui.router')); 

    beforeEach(function() { 
    module('mymodule'); 

    inject(function ($rootScope, _$compile_,_$controller_) { 
     rootScope = $rootScope; 
     compile = _$compile_; 
     $scope = $rootScope.$new(); 

     MyService = jasmine.createSpyObj('MyService', [ 
     'retrieveData' 
     ]); 
     $controller = _$controller_('MyCtrl', { 
     $scope: $scope 
     }); 
    }); 

    }); 




    it('controller should be initialized and data should also be initialized', function() { 

    expect($controller).to.not.be.undefined; 
    expect($controller).to.not.be.null; 
    expect($controller.disableBarCode).to.equal(false); 
    expect($controller.childCount).to.equal(0); 
    expect($controller.headertext).to.equal("Master Container Builder"); 
    }); 

    it(' should process data when containerLabel is called into myfunction', function() { 

    $controller.handKeyed('12001'); 
    expect(MyService.retrieveData).to.have.been.called; 
    expect($controller.processData).to.have.been.called; 
    expect($controller.disableBarCode).to.equal(true); 
    expect($controller.childCount).to.equal(0); 
    expect($controller.headertext).to.equal("Master Container Builder"); 

    }); 
}); 

Ich verwende folgende techstack wenn es hilft:

  1. Winkel 1,5
  2. Ionic
  3. Karma-Jasmin

Der Code funktioniert, wenn ich es laufen. Mein Problem ist, dass es nicht die Daten in meiner Variable Vm.displayData auffüllt, wenn ich den Test ausführe. Wie kann ich dafür sorgen, dass Daten in den Dienst gelangen? Ich fügte einige Protokollanweisungen hinzu und es überspringt es vollständig.

Nach dem Testlauf einschließlich der nicht verwandten Tests zu diesem, dann sehe ich die Protokollanweisungen von MyService. Ich bin mir nicht sicher, wie ich das angehen soll.

Antwort

0

Ich denke, was Sie suchen, ist der $httpBackend Service. Es wird die Anfrage verspotten, die das Ergebnis anzeigt. Wenn Ihr Service also die URL erreicht, wird das, was Sie an die $httpBackend-Konfiguration übergeben haben, zurückgegeben.

Ein einfaches Beispiel wäre:

it('should list newest by category', function(){ 
     $httpBackend 
      .expectGET(url) 
      .respond(techPosts /*YOUR MOCKED DATA*/); 

     $stateParams.category = 'tech';   
     var controller = $controller('HomeCtrl', { PostsResource: PostsResource, $stateParams: $stateParams }); 

     controller.listNewestPosts(); 
     $httpBackend.flush(); 

     expect(controller.posts).toEqual(techPosts.posts); 
    }); 
+0

$ mit httpBackend als Beispiel mir Daten aus dem MyService Service geben tut in MyCtrl genannt zu werden. Ich habe es benutzt, um den Test für meinen Dienst zu schreiben (was funktioniert) – manu