jeudi 4 février 2021

Angular testing: tick cannot advance the time from timers outside its own fakeAsync zone

All the examples I have found so far with tick() are related to the timer being in the same fakeAsync.

Consider you have some kind of initialization that involves setTimeout and you'd like to put it in beforeEach() and advance the clock in the it(). I cannot do it using angular only :(

Please take a look at the examples below. For simplicity the "initialization" consists of a simple setTiemout. Any advice or deeper explanations on the tick misbehavior and if there is a way to overcome it will be much appreciated.

This one always fails, cannot advance the time at all:

describe("counter1", () => {
        let counter = 0;
        beforeEach(() => {
            setTimeout(()=> ++counter, 10);
        });
        it("is incremented", fakeAsync(() => {
            expect(counter).toBe(0); // TRUE
            tick(50);
            expect(counter).toBe(1);  // FALSE; tick() can not advance the timer when it is outside the current fakeAsync
        }));
    });

This is similar to the one above but in addition, there is Error: 1 timer(s) still in the queue. that I cannot get rid of because of the fakeAsync in the beforeEach

    describe("counter1fakeAsync" , () => {
        let counter = 0;
        beforeEach(fakeAsync(() => {
            setTimeout(()=> ++counter, 10);
        }));
        it("is incremented", fakeAsync(() => {
            expect(counter).toBe(0); // TRUE
            tick(50);
            expect(counter).toBe(1);  // FALSE; tick() can not advance the timer when it is outside the current fakeAsync
            // Even more you cannot get rid of `Error: 1 timer(s) still in the queue.`
        }));
    });

This works, all examples on the Ineternet are like this:

    describe("counter2",  () => {
        let counter = 0;
        it("is incremented", fakeAsync(() => {
            setTimeout(()=> ++counter, 10);
            expect(counter).toBe(0); // TRUE
            tick(50);
            expect(counter).toBe(1);  // TRUE; tick() can advance the timer if it is in the same fakeAsync
        }));
    });

jasmine.clock() also works:

    describe("counter3",  () => {
        let counter = 0;
        beforeEach(() => {
            jasmine.clock().uninstall(); // NEEDED :( or try with __zone_symbol__fakeAsyncPatchLock
            jasmine.clock().install();
            setTimeout(()=> ++counter, 10);
        });
        afterEach(() => {
            jasmine.clock().uninstall();
        });
        it("is incremented", () => {
            expect(counter).toBe(0); // TRUE
            jasmine.clock().tick(50);
            expect(counter).toBe(1);  // TRUE; jasmine.clock().tick() just works as expected
        });
    });

Aucun commentaire:

Enregistrer un commentaire