自从开玩笑26&#x2B以来,如何冲洗承诺。

发布于 2025-01-22 16:13:58 字数 1889 浏览 2 评论 0 原文

Jest 26根据 @Sinonjs/Fake-Timers运行了新的假计时器实施。

以前我用过 const flushPromises =()=>新的Promise(setimMediate);

现在,我试图用

等待新的Promise(Process.nexttick);

,如下所述: 但这在某些情况下不起作用。

示例代码在不起作用时(JEST版本:27.5.1):

class SuperFetch {
    public static async get(): Promise<string> {
        return 'never mind';
    }
}

class ClassForTest {
    public async get(): Promise<string> {
        return SuperFetch.get();
    }
}

带有旧式假计时器的Test1:

jest.useFakeTimers('legacy');
describe('Test', () => {

    const flushPromises = (): Promise<void> => new Promise(setImmediate);
    
    test('should flush promise', async () => {
        SuperFetch.get = jest.fn().mockResolvedValue('test');
        const instance = new ClassForTest();
        let result;
        instance.get().then(x => {
            result = x;
        });

        jest.advanceTimersByTime(1000);
        await flushPromises();

        expect(result).toBe('test');
    });
});

带有现代假计时器(失败)

jest.useFakeTimers('modern');
describe('Test', () => {
    test('should flush promise', async () => {
        SuperFetch.get = jest.fn().mockResolvedValue('test');
        const instance = new ClassForTest();
        let result;
        instance.get().then(x => {
            result = x;
        });

        jest.advanceTimersByTime(1000);
        await new Promise(process.nextTick);

        expect(result).toBe('test');
    });
});

失败的 Test2 投掷:“测试超过5000毫秒的超时。 在调试期间,它会在上冻结,等待新的Promise(Process.nexttick)

Jest 26 shipped a new implementation of fake timers based on @sinonjs/fake-timers.

Previously I used
const flushPromises = () => new Promise(setImmediate);

and now I'm trying to replace it with

await new Promise(process.nextTick);

as described here:
How to make Jest wait for all asynchronous code to finish execution before expecting an assertion
but it doesn't work in some cases.

Example code when it doesn't work (jest version: 27.5.1):

class SuperFetch {
    public static async get(): Promise<string> {
        return 'never mind';
    }
}

class ClassForTest {
    public async get(): Promise<string> {
        return SuperFetch.get();
    }
}

Test1 with legacy fake timers (passed):

jest.useFakeTimers('legacy');
describe('Test', () => {

    const flushPromises = (): Promise<void> => new Promise(setImmediate);
    
    test('should flush promise', async () => {
        SuperFetch.get = jest.fn().mockResolvedValue('test');
        const instance = new ClassForTest();
        let result;
        instance.get().then(x => {
            result = x;
        });

        jest.advanceTimersByTime(1000);
        await flushPromises();

        expect(result).toBe('test');
    });
});

Test2 with modern fake timer (failed)

jest.useFakeTimers('modern');
describe('Test', () => {
    test('should flush promise', async () => {
        SuperFetch.get = jest.fn().mockResolvedValue('test');
        const instance = new ClassForTest();
        let result;
        instance.get().then(x => {
            result = x;
        });

        jest.advanceTimersByTime(1000);
        await new Promise(process.nextTick);

        expect(result).toBe('test');
    });
});

Failed with
thrown: "Exceeded timeout of 5000 ms for a test.
During debugging it freezes on await new Promise(process.nextTick)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

自演自醉 2025-01-29 16:13:58

对于我的测试,我正在使用您所描述的 flushpromises 方法:

const flushPromises = () => new Promise(setImmediate);

但是要使这项工作我必须导入 setimmediate

import { setImmediate } from 'timers';

For my test I am using the flushPromises method as you described:

const flushPromises = () => new Promise(setImmediate);

but to make this work I had to import setImmediate:

import { setImmediate } from 'timers';
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文