Модульный тест контроллера директивы Angular с использованием window.confirm

Я пытаюсь получить 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, но я не уверен, смогу ли я это проверить, поскольку он не объявлен глобально. Итак, полностью ли функция контроллера «поддается модульному тестированию»? Если нет, то должен ли я написать контроллер директивы в отдельный файл и использовать angular.module.controller? Если да, то как я могу проверить это, или что я упускаю?


person Healforgreen    schedule 25.01.2016    source источник
comment
Вы знаете, что confirm так же, как и alert, блокирует выполнение скрипта?   -  person charlietfl    schedule 26.01.2016
comment
Он блокирует его, а затем, после того, как вы нажмете «да» или «нет», выполнение скрипта продолжится, верно?   -  person Healforgreen    schedule 26.01.2016
comment
да... вот как это можно использовать в условном... возвращает логическое значение, когда пользователь щелкает по нему   -  person charlietfl    schedule 26.01.2016


Ответы (1)


Используйте угловую службу $window вместо окна напрямую, что вы и делаете. в вашем тесте, но не в вашей директиве.

Затем вы можете издеваться над любой из его функций:

spyOn($window, 'confirm').and.returnValue(false);
person andyhasit    schedule 26.01.2016