Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to test the duration of a $timeout operation using jasmine?

Suppose I have the following anonymous functionality within a directive:

 $timeout(function () {
     element.removeClass('highlighted')
 }, 2000)   

This works successfully. Now, if I wanted to write a test, using jasmine, to ensure the class is removed after ~2s, how would this be done?

I should add that I have attempted using both jasmine.Clock and waitsFor approaches so far, and in both cases, the tests failed. Notably, however, when I change $timeout to setTimeout within my directive, both tests have passed, so angular's behavior seems to be at play here.

(Note that using $timeout.flush() is unsatisfactory here, as it will only prove that the timeout completed, not how long it took).

like image 366
scarlz Avatar asked Jan 22 '14 01:01

scarlz


People also ask

How do I write a test case for setTimeout in Jasmine?

Jasmine supports testing async code. We can test async code with: describe("Using callbacks", function () { beforeEach(function (done) { setTimeout(function () { value = 0; done(); }, 1); }); it("supports sequential execution of async code", function (done) { value++; expect(value). toBeGreaterThan(0); done(); }); });

How do I set timeout on Jasmine?

Current Behavior. The only ways to set test timeout currently are to explicitly set jasmine. DEFAULT_TIMEOUT_INTERVAL = // ... in JavaScript, or to add a timeout to the specific test callback.

What is done () in Jasmine?

Using the done() Method in Your Jasmine-driven Asynchronous JavaScript Tests. Jasmine. Async is an add-on library for Jasmine that provides additional functionality to do asynchronous testing. Modeled after Mocha's async test support, it brings the done() function to the Jasmine unit testing environment.


1 Answers

Beginning in 1.2 $timeout.flush() takes a delay parameter which simulates the clock akin to jasmine.Clock's simulation, but in a way that makes Angular $timeout happy.

So this test will pass:

it("timeout test", function() {
    $timeout(function() {
        timerCallback();
    }, 100);
    expect(timerCallback).not.toHaveBeenCalled();
    $timeout.flush(99);
    expect(timerCallback).not.toHaveBeenCalled();
    $timeout.flush(1);
    expect(timerCallback).toHaveBeenCalled();
});

demo fiddle

like image 137
KayakDave Avatar answered Sep 22 '22 02:09

KayakDave