2015-06-05 3 views
14

Ich habe folgende Controller ViewMeetingCtrl.jsSpy auf einem Service-Methodenaufruf mit Jasmin Spies

(function() { 
    'use strict'; 
    angular.module('MyApp').controller('ViewMeetingCtrl', ViewMeetingCtrl); 

    ViewMeetingCtrl.$inject = ['$scope', '$state', '$http', '$translate', 'notificationService', 'meetingService', '$modal', 'meeting', 'attachmentService']; 

    function ViewMeetingCtrl($scope, $state, $http, $translate, notificationService, meetingService, $modal, meeting, attachmentService) { 
     $scope.meeting = meeting; 

     $scope.cancelMeeting = cancelMeeting; 

     function cancelMeeting(meetingId, companyId) { 
      meetingService.sendCancelNotices(companyId, meetingId) 
       .success(function() { 
        $state.go('company.view'); 
       }); 
     }  
    } 
})(); 

konnte ich succussfully die spyOn aufrufen für cancelMeeting() aber nicht mit der Berufung von sendCancelNotices Methode. Was ich tun möchte ist, ich möchte testen, ob immer cancelMeeting() ruft, ruft es sendCancelNotices() Methode. Ich weiß, dass ich mit createSpy Methode gehen sollte, um dies zu tun. Aber ich bin nicht sicher, wie es geht.

Unten ist der Testfall ViewMeetingCtrlSpec.js

describe('ViewMeetingCtrl CreateSpy --> Spying --> cancelMeeting', function() { 
     var $rootScope, scope, $controller , $q ; 


     var sendCancelNoticesSpy = jasmine.createSpy('sendCancelNoticesSpy'); 


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

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

     it("tracks that the cancelMeeting spy was called", function() { 
      //some assertion 
     }); 

}); 
+2

eigentlich brauchen Sie nur die spyOn Methode wie spyOn verwenden (Service, 'Methode') http: //jasmine.github .io/2.0/einführung.html das wird die ursprüngliche Methode nach der Durchführung der Spion-Operationen –

Antwort

23
describe('ViewMeetingCtrl', function() { 

    var scope, meetingService; 

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

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

    it('should send cancel notices whan cancelMeeting is called', function() { 
     var fakeHttpPromise = { 
      success: function() {} 
     }; 
     spyOn(meetingService, 'sendCancelNotices').andReturn(fakeHttpPromise); 

     scope.cancelMeeting('foo', 'bar'); 

     expect(meetingService.sendCancelNotices).toHaveBeenCalledWith('bar', 'foo'); 
    }); 

}); 

Ich möchte Sie ermutigen Berufung von HTTP Versprechen von Dienstleistungen werden zu stoppen zurückgeführt. Erwägen Sie stattdessen, dass der Dienst ein Versprechen zurückgibt. Diese sind leichter zu verspotten und zwingen Sie nicht dazu, Ihren Controller-Code neu zu schreiben, wenn Sie keine HTTP-Versprechungen mehr zurückgeben.

In Ihrem Controller:

function cancelMeeting(meetingId, companyId) { 
     meetingService.sendCancelNotices(companyId, meetingId) 
      .then(function() { 
       $state.go('company.view'); 
      }); 
    } 

In Ihrem Test:

 var fakePromise = $q.when(); 
     spyOn(meetingService, 'sendCancelNotices')and.returnValue(fakePromise); 

     scope.cancelMeeting('foo', 'bar'); 
     expect(meetingService.sendCancelNotices).toHaveBeenCalledWith('bar', 'foo'); 
+1

Dankeschön für Ihre Antwort. genau das, was ich wollte. Allerdings musste eine kleine Änderung vorgenommen werden (and.returnValue()), da ich jasmine 2.0 verwende. – Malik

+0

Im obigen Code rufen wir spyOn auf (und wir können createSpyObj aufrufen, um das gesamte mocked Objekt zu erhalten) auf der realen Dienstinstanz von MeetingService. In unserem Code erstellen wir gerade ein Spy-Objekt für ein String-Objekt, wobei der Wert des Strings dem Namen des Services entspricht. Wir schreiben etwas: beforeEach (function() {$ provider.factory ("meetingService", function() {meetingServiceMock = jasmine.createSpyObj ("meetingService", ['sendCancelNotices']); gib meetingServiceMock zurück;}) und benutze dieses meetingServiceMock überall in "it" blockt. Auch wenn es richtig funktioniert .. glaube nicht, dass es Sinn macht? –

+0

Es macht Sinn, aber es ist mehr Arbeit, und Sie haben immer das Risiko, einen Schein-Service, der nicht funktioniert haben die gleichen Methoden wie der eigentliche Dienst. –