I want to unittest some code that is part of an AngularJS service,
This service checks for a button, if not present it shows a prompt, if the user clicks ok, it will check for the button again. If available it will click on it.
I stripped it down a bit.
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');
});
}
}
}}
I want to be able to test the branch inside the if (shouldCheckForButtons && checkForBackButton()) {
check part of the " promptBackConfirmation
" function.
The problem is that checkforbutton()
checks if a button is present, if not it prompts the user, if the user presses ok, I must check another time if the button is available. I want that button to be available then in my jasmine unit test. What i have so far:
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();
});
The problem is that the button is not available when jasmine spy return true on prompt, so then button will never be clicked.
ok i figured it out myself: solution is to use .an.callFake to do some stuff (add button) and then return the value
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();
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.