如何使用jasmine测试具有setTimeout的函数?

Nic*_*tti 44 javascript jquery unit-testing settimeout jasmine

我需要为一个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();
    } );
};
Run Code Online (Sandbox Code Playgroud)

这是我的考验

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 );
    } );
} );
Run Code Online (Sandbox Code Playgroud)

我已经尝试使用jasmine.Clock.useMock();jasmine.Clock.tick(11);,但我不能得到的东西的工作,测试从未通过

log*_*yth 65

整体方法因您的Jasmine版本而异.

茉莉花1.3

你可以使用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);
});
Run Code Online (Sandbox Code Playgroud)

你也可以使用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 );
        });
    });
});
Run Code Online (Sandbox Code Playgroud)

也有这样做的第三条道路,而不需要waits,waitsForruns.

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 );
    });
});
Run Code Online (Sandbox Code Playgroud)

茉莉花2.0

你可以使用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);
});
Run Code Online (Sandbox Code Playgroud)

你可以模拟出计时器的行为:

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()
});
Run Code Online (Sandbox Code Playgroud)

  • 在Jasmine 2.0 runs()中,waits()和waitFor()被done()替换 (12认同)

Dom*_*nic 8

从 Jasmine 2 开始,语法发生了变化:http : //jasmine.github.io/2.0/introduction.html#section-Asynchronous_Support

现在,您可以简单地传递一个done回调beforeEachit以及afterEach

it('tests something async', function(done) {
    setTimeout(function() {
        expect(somethingSlow).toBe(true);
        done();
    }, 400);
});
Run Code Online (Sandbox Code Playgroud)

更新:自从写了这篇文章,现在也可以使用async/await我更喜欢的方法。


E. *_*ini 6

对于任何在谷歌上搜索这个的人,可以找到更好的答案计时器测试

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();
 }));
Run Code Online (Sandbox Code Playgroud)