包含 $scope.$on 的测试控制器

testing controller containing $scope.$on

我想在我的模态控制器中测试这两个函数,但我不确定如何测试 $scope.$on 函数。有人有什么想法吗?

 $scope.$on("filesUploaded", function (e, files) {
            for (var i = 0; i < files.length; i++) {
                $scope.images.items.unshift(files[i]);
            }
            $scope.images.total += files.length;
        });

        $scope.$on("filesUploadCompleted", function () {
            if (!$scope.$$phase) $scope.$apply();
        });

到目前为止我的完整测试设置是:

describe('pbImagePickerModalController', function () {
    beforeEach(module('pb.campaigns.controllers'));
    beforeEach(module('ui.router'));
    beforeEach(module('ui.bootstrap'));

    //var mockWindow = {};
    //var mockDocument = {};

    var mockState = {};
    var mockModal = {};
    var mockGlobal = {};
    var mockStateParams = {};
    var mockAccountFileService = {};
    var continuationToken = {};

    beforeEach(inject(function ($q) {
        mockStateParams = {
            accountId: 543,
            length: 12
        };
        mockGlobal = {
            setFormSubmitInProgress: function (boolean) {
                this.formProgress = boolean;
            },
            formProgress: false,
            activeOrganizationId: 0
        };
        mockModalInstance = {
            close: jasmine.createSpy('mockModalInstance.close'),
            dismiss: jasmine.createSpy('mockModalInstance.dismiss'),
            result: {
                then: jasmine.createSpy('mockModalInstance.result.then')
            }
        };

        mockAccountFileService = {
            getFiles: function (activeOrganizationId, accountId, length, continuationToken) {
                var defer = $q.defer();
                defer.resolve(images);
                return defer.promise;
            }
        };
    }));


    beforeEach(inject(function ($rootScope, _$controller_) {
        scope = $rootScope.$new();
        $controller = _$controller_;
        controller = $controller('pbImagePickerModalController', {
            $scope: scope,
            $state: mockState,
            $stateParams: mockStateParams,
            global: mockGlobal,
            accountFileService: mockAccountFileService,
            $modal: mockModal,
            $modalInstance: mockModalInstance,
            //$window: mockWindow,
            //$document: mockDocument,
            accountId: mockStateParams.accountId
            //accountId: function () {
            //    return mockStateParams.accountId;
            //}
        });

    }));

    describe("init() function", function () {

        it('should call getImages()', function () {
            spyOn(scope, 'getImages');
            expect(scope.getImages).toHaveBeenCalledWith(50);
        });

    });

    describe("getImages() function", function () {

        it('should call getFiles with proper params', function () {
            spyOn(mockAccountFileService, 'getFiles').and.callThrough();
            scope.getImages(mockStateParams.length, continuationToken);
            scope.$digest();
            expect(mockAccountFileService.getFiles).toHaveBeenCalledWith(mockGlobal.activeOrganizationId, mockStateParams.accountId, mockStateParams.length, continuationToken);
        });

        it('should assign scope.images to promise result if scope.images does not exist', function () {
            scope.getImages(mockStateParams.length, continuationToken);
            scope.$digest();
            expect(scope.images).toEqual(mockAccountFileService.images);
        });

        describe('with existing images', function () {

            beforeEach(function () {
                var existingLinks = {
                    continuationToken: 0002,
                    total: 2,
                    items: ['sponser_image01.png', 'sponser_image02.png']
                };
                scope.images = existingLinks;
            });

            it('should assign promise continuationToken to scope.images.continuationToken if scope.images exists', function () {

                scope.getImages(mockStateParams.length, continuationToken);
                scope.$digest();
                expect(scope.images.continuationToken).toEqual(mockAccountFileService.images.continuationToken);
            });

            it('should assign promise data and existing images to scope if scope.images exists', function () {

                scope.getImages(mockStateParams.length, continuationToken);
                scope.$digest();
                expect(scope.images.total).toEqual(4);
            });

            it('should push exisiting campaign links to link Array', function () {

                scope.getImages(mockStateParams.length, continuationToken);
                scope.$digest();

                expect(scope.images.items).toEqual(['sponser_image01.png', 'sponser_image02.png', 'sponser_image03.png', 'sponser_image04.png']);
            });

        });

    });


    describe("cancel() function", function () {

        it("changes formProgress from true to false", function () {
            mockGlobal.setFormSubmitInProgress.formProgress = true;
            scope.cancel();
            expect(mockModalInstance.dismiss).toHaveBeenCalled();
            expect(mockGlobal.formProgress).toEqual(false);
        });

    });

});

我的完整控制器是:

angular.module('pb.campaigns.controllers')
    .controller('pbImagePickerModalController', ['$window', '$scope', '$document', '$modal', '$modalInstance', 'global', 'accountId', 'accountFileService', function ($window, $scope, $document, $modal, $modalInstance, global, accountId, accountFileService) {

        $scope.currentAccountId = accountId;

        var init = function () {
            $scope.getImages(50);
        };

        $scope.getImages = function (length, continuationToken) {
            // show all existing images
            accountFileService.getFiles(global.activeOrganizationId, accountId, length, continuationToken).then(function (data) {
                if ($scope.images) {
                    $scope.images.continuationToken = data.continuationToken;
                    $scope.images.total += data.total;
                    angular.forEach(data.items, function (value, key) {
                        $scope.images.items.push(data.items[key]);
                    });
                } else {
                    $scope.images = data;
                }
            });
        };

        init();

        $scope.$on("filesUploaded", function (e, files) {
            for (var i = 0; i < files.length; i++) {
                $scope.images.items.unshift(files[i]);
            }
            $scope.images.total += files.length;
        });

        $scope.$on("filesUploadCompleted", function () {
            if (!$scope.$$phase) $scope.$apply();
        });

        //$scope.add = function (accountId, file) {
        //    global.setFormSubmitInProgress(true);

        //    accountFileService.createFile(global.activeOrganizationId, accountId, file).then(function () {
        //        global.setFormSubmitInProgress(false);
        //        $modalInstance.close();
        //    },
        //    function (errorData) {
        //        global.setFormSubmitInProgress(false);
        //    });

        //};

        $scope.select = function (image) {
            $modalInstance.close(image);
        };

        $scope.cancel = function () {
            global.setFormSubmitInProgress(false);
            $modalInstance.dismiss('cancel');
        };

    }]);

你可以用 rootScope 本身来测试它。

示例:-

$rootScope.$broadcast('filesUploaded', fileListStub); //broadcast the event with stub data
scope.$digest(); //Triger digest cycle to invoke on handler
expect(scope.images.total).toEqual(fileListStub.length+whateverinitialcount);

Demo