Angular指令控制器单元测试使用window.confirm

时间:2016-01-25 22:21:19

标签: javascript angularjs unit-testing jasmine

我正试图获得100%的指令测试覆盖率。该指令有一个控制器,其函数使用window.confirm方法。

'use strict';

(function() {

    angular
        .module('app')
        .directive('buttonToggle', buttonToggle);

    function buttonToggle() {
        var buttonToggleController = ['$scope', function($scope) {
            $scope.toggle = function() {
                var confirmResponse = (window.confirm('Are you sure?') === true);

                if(confirmResponse) {
                    $scope.on = !$scope.on;
                }
                return $scope.on;
            };
        }];

        return {
            restrict: 'E',
            templateUrl: 'client/modules/buttonToggle/buttonToggle.html',
            replace: true,
            scope: {
                on: '='
            },
            controller: buttonToggleController
        };
    }
})();

我已经过测试以确保所有内容都已定义,但我无法在控制器的if方法中输入$scope.toggle语句。

describe('The buttonToggle directive', function() {

    var $compile,
        $scope,
        btElement = '<button-toggle></button-toggle>',
        compiledElement,
        window,
        confirm,
        btElementPath = 'client/modules/buttonToggle/buttonToggle.html',
        btController;

    beforeEach(module('app'));
    beforeEach(module(btElementPath));

    beforeEach(inject(function(_$compile_, _$rootScope_, $templateCache, $window) {
        $compile = _$compile_;
        window = $window;
        spyOn(window, 'confirm');
        $scope = _$rootScope_.$new();
        var template = $templateCache.get(btElementPath);
        $templateCache.put(btElementPath, template);
        var element = angular.element(btElement);
        compiledElement = $compile(element)($scope);
        $scope.$digest();
        btController = element.controller('buttonToggle', {
            $window: window
        });
        scope = element.isolateScope() || element.scope();
    }));

    it('should be defined', function() {
        expect(compiledElement.html()).toContain('btn');
    });

    describe('buttonToggle controller', function() {
        it('should be defined', function() {
            expect(btController).not.toBeNull();
            expect(btController).toBeDefined();
        });

        describe('toggle', function() {
            it('should be defined', function() {
                expect(scope.toggle).toBeDefined();
            });

            it('should confirm the confirmation dialog', function() {
                scope.toggle();
                expect(window.confirm).toHaveBeenCalled();
            });
        });
    });
});

我猜它与模拟$window服务有关,但我不确定我是否能够测试它,因为它不是全局声明的。那么,控制器的功能是否完全可以单元测试&#34;?如果没有,我应该将指令的控制器写在一个单独的文件中并使用angular.module.controller吗?如果是,那我怎么能测试它,或者我错过了什么?

1 个答案:

答案 0 :(得分:1)

直接使用angular $window服务代替窗口,这是您在测试中所做的,而不是在您的指令中。

然后你可以模拟它的任何功能:

spyOn($window, 'confirm').and.returnValue(false);