wie

7
$ state.params in Jasmin Unit-Tests verspotten

Ich habe folgenden Controller EditMeetingCtrl.jswie

(function() { 
    'use strict'; 

    angular 
     .module('myApp') 
     .controller('EditMeetingCtrl', EditMeetingCtrl); 

    EditMeetingCtrl.$inject = ['$rootScope', '$scope', '$state', '$http', '$translate', 
     'meetingService', 'companyService', 'notificationService', 'meeting']; 

function EditMeetingCtrl($rootScope, $scope, $state, $http, $translate, meetingService, companyService, notificationService, meeting) { 
     $scope.meeting = meeting; 

     $scope.companyId = $state.params.companyId; 
     $scope.save = save; 


     function save() { 
      $scope.buttonDisable = true; 
      meetingService.saveMeeting($state.params.companyId, $state.params.meetingId, $scope.meeting) 
       .success(function(meetingId) { 
        //more code 
       }); 
     } 


} 
})(); 

EditMeetingCtrlSpec.js Testfall

describe('in EditMeetingCtrl', function() { 

    var companyService , meetingService ; 

    meetingId = 123321 ;      
    companyId = 456654 ; 
    meetingObj = {} ; 

    var fakeHttpPromise = { 
          success: function() {} 
          }; 

    beforeEach(angular.mock.module('myApp')); 

    beforeEach(angular.mock.inject(function (_$httpBackend_, _companyService_ , _meetingService_) { 
     $httpBackend = _$httpBackend_; 
     companyService = _companyService_; 
     meetingService = _meetingService_ ; 
    })); 

    describe('EditMeetingCtrl.save()', function() { 
     var $rootScope, scope, $controller , $q ; 

     beforeEach(inject(function ($rootScope, $controller , _meetingService_) { 
      scope = $rootScope.$new(); 
      createController = function() { 
       return $controller('EditMeetingCtrl', { 
       $scope: scope, 
       meeting : {} , 
       meetingService : _meetingService_ 
       }); 
      }; 
      var controller = new createController(); 
     })); 

     it("should save the meeting object", function() { 
      spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise); 
      scope.save(); 
      expect(meetingService.saveMeeting).toHaveBeenCalledWith(meetingId , companyId , meetingObj); 
     }); 

    }); 

}); 

Wenn versuchen, den unter Test casse EditMeetingCtrlSpec läuft .js ich habe folgenden Testfehler

PhantomJS 1.9.8 (Windows 8) EditMeetingCtrl Spying --> EditMeetingCtrl.save() should save the meeting FAILED 
     Expected spy saveMeeting to have been called with [ 123321, 456654, Object({ }) ] but actual calls were [ undef 
ined, undefined, Object({ }) ]. 

So die Art verstehen mein dieses Problem, das Service-Anruf für save() Methode enthält $state.params.companyId, $state.params.meetingId Parameter und es sendet eine undefined Werte, wenn der Service-Aufruf aufgerufen wird. Daher muss ich die $state.params verspotten. Nicht sicher, wie es geht. Kann mir jemand in die richtige Richtung zeigen?

EDIT nach Michael Radionov

describe('EditMeetingCtrl.save()', function() { 
     var $rootScope, scope, $controller , $q , $state ; 

     beforeEach(inject(function ($rootScope, $controller , $state , _meetingService_) { 
      scope = $rootScope.$new(); 
      createController = function() { 
       return $controller('EditMeetingCtrl', { 
       $scope: scope, 
       meeting : {} , 
       meetingService : _meetingService_ 
       }); 
      }; 
      var controller = new createController(); 
     })); 

     it("should save the meeting", function() { 
      $state.params = { companyId: 123, meetingId: 567 }; 
      spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise); 
      scope.save(); 
      //expect(meetingService.saveMeeting).toHaveBeenCalledWith(meetingId , companyId , meetingObj); 
     }); 

    }); 

Antwort habe ich die oben getan, aber ich bekomme die folgende Fehlermeldung, Zustand $ ist nicht definiert.

Firefox 38.0.0 (Windows 8.1) In EditMeetingCtrl EditMeetingCtrl.save() should save the meeting FAILED 
     TypeError: $state is undefined in C:/Users/sal/Documents/myApp/test/meeting/EditMe 
etingCtrlSpec.js (line 80) 

Ich nahm dies geschah, weil ich das nicht getan hätte ->$state : state in der Inject Methode, so habe ich versucht, das zu tun, aber den gleichen Fehler hätte. Was fehlt mir hier?

Antwort

15

Sie können die gesamten $state Anbieter verspotten und dann genau festlegen, welche Werte sind Sie in der params Eigenschaft sein wollen, bevor save Aufruf:

describe('in EditMeetingCtrl', function() { 

    // ... 
    beforeEach(angular.mock.module('myApp')); 

    beforeEach(angular.mock.module(function ($provide) { 

     // mock the entire $state provider 
     $provide.provider('$state', function() { 
      return { 
       $get: function() { 
        return { 
         // by default it will be an empty object 
         params: {} 
        }; 
       } 
      }; 
     }); 

    })); 

    // .... 

    describe('EditMeetingCtrl.save()', function() { 

     // inject mocked $state - one that you've provided above 

     var $rootScope, scope, $controller, $q, state; 
     // ---------------------------------------^^^ 

     beforeEach(inject(function ($rootScope, $controller, $state, _meetingService) { 
      // ------------------------------------------------^^^ 
      state = $state; 
     })); 

     // ... 

     it("should save the meeting object", function() { 

      // provide custom params which will be used in a call 
      state.params = { companyId: 123, meetingId: 567 }; 

      spyOn(meetingService, 'saveMeeting').and.returnValue(fakeHttpPromise); 
      scope.save(); 
      expect(meetingService.saveMeeting).toHaveBeenCalledWith(meetingId , companyId , meetingObj); 
     }); 
    }); 

    // ... 

}); 
+0

Vielen Dank für Ihre Antwort. Bitte sieh dir den Schnitt an, den ich in meiner Frage gemacht habe. ? was mache ich falsch? – Malik

+1

Ich denke es liegt an falschen Variablennamen. Verwenden Sie 'var state;', verwenden Sie beim Injizieren 'state = $ state' und verwenden Sie' state.params' im 'it'-Block. Ich habe meine Antwort aktualisiert, siehe Link zum Bearbeiten. –

+0

Danke !! . Das hat funktioniert . und jetzt weiß ich, was ich falsch gemacht habe :) – Malik