Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spec for async functions using Jasmine

When I'm trying to test _.debounce function like in this qunit test using jasmine something strange happens.

Seems like it could be tested using jasmine.Clock.useMock()... But when I write:

it('_.debounce()', function () {
    var spy = jasmine.createSpy('debounce'),
        debouncedSpy = _.debounce(spy, 100);

    jasmine.Clock.useMock();

    // direct calls
    debouncedSpy();
    debouncedSpy();
    debouncedSpy();

    // timed out calls
    setTimeout(debouncedSpy, 60);
    setTimeout(debouncedSpy, 120);
    setTimeout(debouncedSpy, 180);
    setTimeout(debouncedSpy, 240);
    setTimeout(debouncedSpy, 300);

    jasmine.Clock.tick(300);
    expect(spy).toHaveBeenCalled();

    jasmine.Clock.tick(400);
    expect(spy).toHaveBeenCalled();

    jasmine.Clock.tick(1000);
    expect(spy.callCount).toBe(1);
});

It doesn't work (call count is equal 3). But without direct calls (or when I'm using setTimeout(..., 0)) everything works fine. What I'm doing wrong?

Also I've try to do it through runs and waits, and it works. But why it doesn't work in previous example?

it('should be called once', function () {
    var spy = jasmine.createSpy('debounce'),
        debouncedSpy = _.debounce(spy, 100);

    runs(function () {
        debouncedSpy();
        debouncedSpy();
        debouncedSpy();

        expect(spy).not.toHaveBeenCalled();

        setTimeout(debouncedSpy, 60);
        setTimeout(debouncedSpy, 120);
        setTimeout(debouncedSpy, 180);
        setTimeout(debouncedSpy, 240);
        setTimeout(debouncedSpy, 300);
    });

    waits(800);

    runs(function () {
        expect(spy.callCount).toBe(1);
    });
});
like image 883
ValeriiVasin Avatar asked Jul 30 '26 03:07

ValeriiVasin


2 Answers

Until https://github.com/pivotal/jasmine/issues/361 and https://github.com/pivotal/jasmine/pull/455. are released, you add this to your tests to have Jasmine skip the debounce delay.

_.debounce = function (func) { return function () { func.apply(this, arguments);}; };
like image 138
Ev Haus Avatar answered Aug 03 '26 13:08

Ev Haus


The jasmine mock clock only changes the behavior of setTimeout and it's ilk, it currently doesn't mock out Date see https://github.com/pivotal/jasmine/issues/361 and https://github.com/pivotal/jasmine/pull/455. Using runs and waitsFor (or in jasmine 2.0 done callbacks), actually lets the time pass so the browser actually changes the Date value so the date math that happens inside debounce adds up.

like image 22
Gregg Avatar answered Aug 03 '26 13:08

Gregg



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!