web-dev-qa-db-fra.com

Espionner un appel de méthode de service en utilisant des espions de jasmin

J'ai le contrôleur suivant ViewMeetingCtrl.js

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

J'ai pu invoquer avec succès le spyOn pour cancelMeeting () mais pas avec l'appel de la méthode sendCancelNotices. Ce que je veux faire, c'est que je veux tester que chaque fois que cancelMeeting () est appelé, il appelle la méthode sendCancelNotices (). Je sais que je devrais utiliser la méthode createSpy pour ce faire. Mais je ne sais pas comment le faire.

Ci-dessous, le cas de test 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
        });

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

});

Je vous encourage à ne plus vous fier aux promesses HTTP renvoyées par les services. Considérez plutôt le service comme une promesse. Celles-ci sont plus faciles à simuler et ne vous obligeront pas à réécrire le code de votre contrôleur lorsque vous ne retournez plus de promesses HTTP.

Dans votre contrôleur:

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

Dans votre test:

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

        scope.cancelMeeting('foo', 'bar');
        expect(meetingService.sendCancelNotices).toHaveBeenCalledWith('bar', 'foo');
29
JB Nizet