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

标签 angularjs unit-testing jasmine karma-runner karma-jasmine

我有以下 Controller 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');
                });
        }      
    }
})();

我能够成功调用 的 spyOn取消 session ()但不是通过 的召唤发送取消通知 方法。我想做的是,我想在任何时候测试 取消 session ()被调用,它调用 发送取消通知() 方法 。我知道我应该使用 createSpy 方法来执行此操作。但我不知道该怎么做。

下面是测试用例 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');
    });

});

我鼓励您停止依赖从服务返回的 HTTP promise 。相反,只需考虑服务返回一个 promise 。这些更容易模拟,并且当您不再返回 HTTP promise 时,不会强制您重写 Controller 代码。

在您的 Controller 中:
    function cancelMeeting(meetingId, companyId) {
        meetingService.sendCancelNotices(companyId, meetingId)
            .then(function () {
                $state.go('company.view');
            });
    } 

在您的测试中:
        var fakePromise = $q.when();
        spyOn(meetingService, 'sendCancelNotices')and.returnValue(fakePromise);

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

关于angularjs - 使用 jasmine Spies 监视服务方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30658525/

相关文章:

c# - 等待 Async Void 方法调用以进行单元测试

javascript - 返回值和/或违反 JavaScript 中的 promise

angularjs - 等待 Protractor 与页面同步时出错 : in Protractor IE11 execution

javascript - 从服务器 json Angular 加载数据

javascript - 如何将 ng-click 绑定(bind)到插入指令嵌入 HTML block 内的 HTML block

unit-testing - 编写由多个测试用例组成的单个单元测试违反了单元测试原则?

angularjs - Angular 和 Jasmine : How to test requestError/rejection in HTTP interceptor?

javascript - 无法访问我的 Controller Angular.js 1.3 中的属性

javascript - 将 question_id 添加到用户模式 Angular 中的书签列表

java - 运行忽略@Before/@After 的 Junit @Test