内部にsetTimeout()
呼び出しがある関数のテストを書く必要がありますが、どうすればいいのかわかりません。
これが機能です
_// 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();
} );
};
_
そして、これは私のテストです
_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 );
} );
} );
_
jasmine.Clock.useMock();
とjasmine.Clock.tick(11);
を使用しようとしましたが、動作させることができませんでした。テストはパスしません
全体的なアプローチは、ジャスミンのバージョンによって異なります。
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);
});
どれくらいの時間がかかるか正確にわかっている場合は、waits
を使用することもできます。
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 );
});
});
});
waits
、waitsFor
、およびruns
を必要としない、これを行う3番目の方法もあります。
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 );
});
});
テストコールバックであるdone
を使用できます。
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);
});
タイマーの動作をモックアウトできます。
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()
});
ジャスミンを使ってテストしたことは一度もありませんが、あなたの問題を理解していると思います。次のようなプロキシ関数で呼び出される関数をラップできるように、コードを少し再構築します。
テスト中のコードを変更して、setTimeoutコードを別の関数に抽出します。
元のコード:
// 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();
} );
};
変更されたコード:
// 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 );
}
}
次に、テストコードを次のように変更します。
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) );
});
Jasmine 2以降、構文が変更されました: http://jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support
done
、beforeEach
、およびit
にafterEach
コールバックを単に渡すことができます。
it('tests something async', function(done) {
setTimeout(function() {
expect(somethingSlow).toBe(true);
done();
}, 400);
});
更新:これを書いているので、async/await
これは私の好みのアプローチです。
これをグーグルで探している人には、より良い答えを見つけることができます タイマーテスト
import { fakeAsync, tick, discardPeriodicTasks } from '@angular/core/testing';
it('polls statusStore.refreshStatus on an interval', fakeAsync(() => {
spyOn(mockStatusStore, 'refreshStatus').and.callThrough();
component.ngOnInit();
expect(mockStatusStore.refreshStatus).not.toHaveBeenCalled();
tick(3001);
expect(mockStatusStore.refreshStatus).toHaveBeenCalled();
tick(3001);
expect(mockStatusStore.refreshStatus).toHaveBeenCalledTimes(2);
discardPeriodicTasks();
}));