jasmine超时与window.prompt结合使用

时间:2017-05-10 10:06:29

标签: javascript angularjs jasmine

我想单元测试一些AngularJS服务的代码,

此服务检查按钮,如果不存在则显示提示,如果用户单击“确定”,则会再次检查按钮。如果可用,它将点击它。

我把它剥了一下。

var mod = angular

.module('modulename', []).service('backButtonService', backButtonService);

function backButtonService($timeout, $window) {
var service = {
    executeBackAction: executeBackAction
};

return service;

function executeBackAction() {
    if (checkForBackButton()) {
        // not usefull for this case
    } else {
        promptBackConfirmation(true);
    }
}

function checkForBackButton() {
    return document.querySelectorAll('.button').length > 0;
}

function promptBackConfirmation(shouldCheckForButtons) {
    let answer = $window.confirm('some text');
    if (answer) {
        if (shouldCheckForButtons && checkForBackButton()) {
            $timeout(() => {
                angular.element(document.querySelector('.button')).triggerHandler('click');
            });
        }
    }
}}

我希望能够在“if (shouldCheckForButtons && checkForBackButton()) {”函数的promptBackConfirmation检查部分内测试分支。

问题是checkforbutton()检查是否存在按钮,如果没有提示用户,如果用户按下确定,我必须再次检查该按钮是否可用。我希望那个按钮在我的茉莉花单元测试中可用。到目前为止我所拥有的:

it('should click on the button second time (if avaible while reading window.prompt message for x sec', function () {
    var button = {
        clicked: function () {
            console.info('clicked on button');
        }
    };

    spyOn(button, 'clicked');

    backbuttonService.executeBackAction();

    //this should return after 5 seconds, so it look like user waits 5 sec to press true in prompt window
    spyOn(window, 'confirm').and.returnValue(true);

    // this should execute after 2 sec while the user sees the window.prompt for 5 sec or so this button will be avaible
    var buttonHtml = '<button id="testClick" class="pifczdi-back-button">click</button>';
    createHtml(buttonHtml);
    angular.element(document.getElementById('testClick')).on('click', function () {
        button.clicked();
    });

    $timeout.flush();

    expect(button.clicked).toHaveBeenCalled();
});

问题是当jasmine spy在提示符下返回true时按钮不可用,因此永远不会点击按钮。

1 个答案:

答案 0 :(得分:0)

好吧我自己想通了:解决方法是使用.an.callFake做一些事情(添加按钮)然后返回值

it('should click on the button second time (if available while reading window.prompt message for x sec', function () {
        var html = '<div id="testHtml"></div>';
        createHtml(html);

        var button = {
            clicked: function () {
                console.info('clicked on button');
            }
        };

        spyOn(window, 'confirm').and.callFake(function () {
            var parent = document.getElementById('testHtml');
            var buttonHtml = '<button id="testClick" class="button">click</button>';
            createHtml(buttonHtml, parent);
            angular.element(document.getElementById('testClick')).on('click', function () {
                button.clicked();
            });
            return true;
        });

        backbuttonService.executeBackAction();

        spyOn(button, 'clicked');

        $timeout.flush();

        expect(button.clicked).toHaveBeenCalled();
    });