Spec for async functions using Jasmine

2019-07-04 06:56发布

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);
    });
});

2条回答
一纸荒年 Trace。
2楼-- · 2019-07-04 07:05

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.

查看更多
来,给爷笑一个
3楼-- · 2019-07-04 07:25

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);}; };
查看更多
登录 后发表回答