'Typescript jest Expect executes before timed async functions finish awaits

My problem is that I have polling service, which has Begin() and Halt() methods, that starts or stops an interval, via setInterval

Here's a simplified model that replicated the problem as it is.

class IntervalTestCandidate{

    public Data: string[] = new Array();

    private handle: NodeJS.Timer;

    private async component(){
        console.log('something');
    }

    private async obtainData(): Promise<string[]>{
        await this.component(); //If this line is commented out things work as they should
        return ["hello", "world"];
    }

    private async poll(){
        console.log("this is executed");

        let data = await this.obtainData();
        data.forEach(s => this.Data.push(s));
    }

    public Begin(){
        if(!this.handle)
            this.handle = setInterval(this.poll.bind(this), 1000);
    }

    public Halt(){
        if(this.handle){
            clearInterval(this.handle);
            this.handle = null;
        }
    }

}

jest.useFakeTimers();
it('Test Polling', async () => {
    let cand = new IntervalTestCandidate();
    cand.Begin();
    jest.advanceTimersByTime(1001); 
    await Promise.resolve(); 
    expect(cand.Data.length).toBe(2);
});

It seems to have to do with the nested await, So there can be awaits in poll() but if those awaited methods in turn have awaits, it does not work. What I do not understand is why, and if there is a way that I can fix this somehow.

Small Update: After kicking it around for a bit i found out that adding two extra await Promise.resolve() before the expect makes it work. I wouldn't consider this a fix though. Does it have to do with how it switches between Promisejobs?

jest.useFakeTimers();
it('Test Polling', async () => {
    let cand = new IntervalTestCandidate();
    cand.Begin();
    jest.advanceTimersByTime(1001); 
    await Promise.resolve(); 
    await Promise.resolve(); 
    await Promise.resolve(); 
    expect(cand.Data.length).toBe(2);
});

I have done a lot of googling/DuckDuckGoing, but without any luck. Can someone tell me what the problem is, and show me how to do this properly?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source