3

I have a simple function which fades in an element:

CODE

checkLengthSelect: function(){
    if($(this).val() != ''){ // if not empty
        $('.c--error').fadeOut('fast', function(){
            $('#button').fadeIn();
        })
    } else { // if empty hide button and show error message
        $('#button').fadeOut('fast', function(){
            $('.c--error').html('foo').fadeIn(); // <-- I want to test this on fadeOut callback
        })
    }
},

I'm trying to write a test for it like this:

TEST

it("it should have a value or hide continue button", function(){

    // check cover length on select
    $(document).on('change', '#select', function(){ qqw.validate.checkLengthSelect.call(this) } );

    // force a change event to fire with empty value.
    $('#select').val('').change();

    setTimeout(function(){
        expect($('.c--error').html()).toEqual('foo');   
        done(); // <-- test if done
    }, 800);

});

ERROR

This shows in console

'expect' was used when there was no current spec, this could be because an asynchronous test timed out

QUESTION

How can I test that an event happens when the fadeOut completes?

I'm using Jasmine v2+

StudioTime
  • 22,603
  • 38
  • 120
  • 207
  • Does this answer your question? [How to test a function which has a setTimeout with jasmine?](https://stackoverflow.com/questions/10955201/how-to-test-a-function-which-has-a-settimeout-with-jasmine) – Top-Master Mar 15 '22 at 18:43

2 Answers2

2

Jasmine 1.3

You can use waitsFor to wait for the condition or fail after a timeout:

waitsFor(function() {
  return $('.c--error').html() == 'foo';
}, "Error was never set to 'foo'", 800);

Jasmine 2.0

For Jasmine 2.0, you can simulate the same behavior:

describe("stackoverflow test", function() {
    var originalTimeout;
    beforeEach(function() {
      originalTimeout = jasmine.DEFAULT_TIMEOUT_INTERVAL;
      jasmine.DEFAULT_TIMEOUT_INTERVAL = 10000;
    });

    it("it should have a value or hide continue button", function(done) {

        // check cover length on select
        $(document).on('change', '#select', function(){ checkLengthSelect.call(this) } );

        // force a change event to fire with empty value.
        $('#select').val('').change();

        var POLL_TIME = 10;
        var endTime = new Date().getTime() + 5000;

        var checkCondition = function() {
            if (new Date().getTime() <= endTime && $('.c--error').html() != 'foo') {
                setTimeout(checkCondition, POLL_TIME);
            } else {
                expect($('.c--error').html()).toEqual('foo');  
                done();
            }
        };
        checkCondition();
    });

    afterEach(function() {
      jasmine.DEFAULT_TIMEOUT_INTERVAL = originalTimeout;
    });
});

You need to increase the async timeout to keep the test from failing. Adjust POLL_TIME or the amount added to the current date to change that behavior. I should also note that your current code will not hit the correct branch of checkLengthSelect so the test will fail, I flipped the condition on that branch in my testing to make sure the Jasmine part of this works as expected.

Jake Cobb
  • 1,811
  • 14
  • 27
1

use

jasmine.clock().tick(801);

to advance the timer.

http://jasmine.github.io/2.4/introduction.html

Dave Bush
  • 2,382
  • 15
  • 12