简体   繁体   English

使用jasmine Spies监视服务方法调用

[英]Spy on a service method call using jasmine Spies

I have the following controller ViewMeetingCtrl.js 我有以下控制器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');
                });
        }      
    }
})();

I was able to succussfully invoke the spyOn for cancelMeeting() but not with the calling of sendCancelNotices method. 我能够成功地调用spyOn for cancelMeeting(),但不能调用sendCancelNotices方法。 What i want to do is , i want to test that whenever cancelMeeting() gets called , it calls sendCancelNotices() method . 我想要做的是,我想测试cancelMeeting每当()被调用,它调用sendCancelNotices()方法。 I know that i should go with createSpy method to do this . 我知道我应该使用createSpy方法来执行此操作。 But i am not sure how to do it . 但我不知道该怎么做。

Below is the test case ViewMeetingCtrlSpec.js 下面是测试用例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
        });

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

});

I would encourage you to stop relying of HTTP promises being returned from services. 我鼓励你停止依赖从服务返回的HTTP承诺。 Instead, just consider the service returns a promise. 相反,只需考虑服务返回一个承诺。 Those are easier to mock, and won't force you to rewrite your controller code when you don't return HTTP promises anymore. 这些更易于模拟,并且当您不再返回HTTP承诺时,不会强制您重写控制器代码。

In your controller: 在你的控制器中:

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

In your test: 在你的测试中:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM