javascript - loop - ¿Cómo probar una función que tiene un setTimeout con jazmín?
timer jquery ejemplos (3)
Necesito escribir una prueba para una función que tenga una llamada setTimeout()
dentro, pero no puedo encontrar cómo debería hacerlo.
Esta es la función
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( ''type'', ''hidden'' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn''t work in chrome.
setTimeout(function() {
$( ''#facebook input[type=submit]'' ).prop( ''disabled'', true );
}, 10);
// unbind all click handler from ajax
$( ''#facebook a.btn'' ).unbind( "click" );
// Disable all AJAX buttons.
$( ''#facebook a.btn'' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
Y esta es mi prueba
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
console.log( ''f'' );
expect( el ).toHaveProp( ''disabled'', true );
} );
} );
He intentado usar jasmine.Clock.useMock();
y jasmine.Clock.tick(11);
pero no pude hacer que las cosas funcionaran, la prueba nunca pasó
Desde Jasmine 2 la sintaxis ha cambiado: http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
Ahora puede simplemente pasar una devolución de llamada done
a beforeEach
, it
y afterEach
:
it(''tests something async'', function(done) {
setTimeout(function() {
expect(somethingSlow).toBe(true);
done();
}, 400);
});
El enfoque general varía según tu versión de Jasmine.
Jasmine 1.3
Puede usar waitsFor
:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// Wait 100ms for all elements to be disabled.
waitsFor(''button to be disabled'', function(){
var found = true;
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
if (!el.prop(''disabled'')) found = false;
});
return found;
}, 100);
});
También puede usar waits
si sabe exactamente cuánto tiempo tomará:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
// Wait 20ms before running ''runs'' section.
waits(20);
runs(function(){
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
expect( el ).toHaveProp( ''disabled'', true );
});
});
});
También hay una tercera forma de hacer esto, sin la necesidad de waits
, waitsFor
y runs
.
it( "Disable all submit buttons", function() {
jasmine.Clock.useMock();
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
jasmine.Clock.tick(10);
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
expect( el ).toHaveProp( ''disabled'', true );
});
});
Jasmine 2.0
Puede usar done
, callback de prueba:
it( "Disable all submit buttons", function(done) {
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
utility_functions.block_all_submit_and_ajax( $button.get(0) );
setTimeout(function(){
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
expect( el ).toHaveProp( ''disabled'', true );
});
// Let Jasmine know the test is done.
done();
}, 20);
});
puedes simular el comportamiento del temporizador:
it( "Disable all submit buttons", function() {
jasmine.clock().install();
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
jasmine.clock().tick(10);
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
expect( el ).toHaveProp( ''disabled'', true );
});
jasmine.clock().uninstall()
});
Nunca hice ninguna prueba con jazmín, pero creo que entiendo tu problema. Me gustaría reestructurar el código un poco para permitir que envuelva la función que se llama en una función de proxy como esta:
Modifique su código que se está probando para extraer el código setTimeout en otra función:
Código original:
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( ''type'', ''hidden'' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn''t work in chrome.
setTimeout(function() {
$( ''#facebook input[type=submit]'' ).prop( ''disabled'', true );
}, 10);
// unbind all click handler from ajax
$( ''#facebook a.btn'' ).unbind( "click" );
// Disable all AJAX buttons.
$( ''#facebook a.btn'' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
Código modificado:
// Disables all submit buttons after a submit button is pressed.
var block_all_submit_and_ajax = function( el ) {
// Clone the clicked button, we need to know what button has been clicked so that we can react accordingly
var $clone = $( el ).clone();
// Change the type to hidden
$clone.attr( ''type'', ''hidden'' );
// Put the hidden button in the DOM
$( el ).after( $clone );
// Disable all submit button. I use setTimeout otherwise this doesn''t work in chrome.
setTimeout(disableSubmitButtons, 10);
// unbind all click handler from ajax
$( ''#facebook a.btn'' ).unbind( "click" );
// Disable all AJAX buttons.
$( ''#facebook a.btn'' ).click( function( e ) {
e.preventDefault();
e.stopImmediatePropagation();
} );
};
var utilityFunctions =
{
disableSubmitButtons : function()
{
$( ''#facebook input[type=submit]'' ).prop( ''disabled'', true );
}
}
A continuación, modificaría el código de prueba de esta manera:
it( "Disable all submit buttons", function() {
// Get a button
var $button = $( ''#ai1ec_subscribe_users'' );
var originalFunction = utilityFunctions.disableSubmitButtons;
utilityFunctions.disableSubmitButtons = function()
{
// call the original code, and follow it up with the test
originalFunction();
// check that all submit are disabled
$( ''#facebook input[type=submit]'' ).each( function( i, el ) {
console.log( ''f'' );
expect( el ).toHaveProp( ''disabled'', true );
});
// set things back the way they were
utilityFunctions.disableSubmitButtons = originalFunction;
}
// Call the function
utility_functions.block_all_submit_and_ajax( $button.get(0) );
});