使用带有Jest的setTimeout测试Promise [英] Testing a Promise using setTimeout with Jest

查看:1012
本文介绍了使用带有Jest的setTimeout测试Promise的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试理解Jest的异步测试。

I'm trying to understand Jest's asynchronous testing.

我的模块有一个接受布尔值并返回值的Promise的函数。执行器函数调用 setTimeout ,并且在超时回调中,promise根据最初提供的布尔值来解析或拒绝。代码如下所示:

My module has a function which accepts a boolean and returns a Promise of a value. The executer function calls setTimeout, and in the timed out callback the promise resolves or rejects depending on the boolean initially supplied. The code looks like this:

const withPromises = (passes) => new Promise((resolve, reject) => {
    const act = () => {
    console.log(`in the timout callback, passed ${passes}`)
        if(passes) resolve('something')
        else reject(new Error('nothing'))
    }

    console.log('in the promise definition')

    setTimeout(act, 50)
})

export default { withPromises }

我想用Jest测试一下。我想我需要使用Jest提供的模拟定时器,所以我的测试脚本看起来有点像这样:

I'd like to test this using Jest. I guess that I need to use the mock timers Jest provides, so my test script looks a bit like this:

import { withPromises } from './request_something'

jest.useFakeTimers()

describe('using a promise and mock timers', () => {
    afterAll(() => {
        jest.runAllTimers()
    })


    test('gets a value, if conditions favor', () => {
        expect.assertions(1)
        return withPromises(true)
            .then(resolved => {
                expect(resolved).toBe('something')
            })
    })
})

我收到以下错误/测试失败,无论我是否打电话 jest.runAllTimers()

I get the following error/failed test, whether or not I call jest.runAllTimers()

Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.

你能解释一下我出错的地方以及我可以做些什么来获得通过测试promise按预期结算?

Can you explain where I'm going wrong and what I might do to get a passing test that the promise resolves as expected?

推荐答案

的调用jest.useFakeTimers()使用必须控制的计时器模拟每个计时器功能。您可以手动前进,而不是自动运行计时器。 jest。 runTimersToTime(msToRun) 函数会将其提前 msToRun 毫秒。在每个计时器都已经过去之前你想要快进是很常见的,计算所有计时器完成所需的时间会非常麻烦,所以Jest提供了 jest.runAllTimers() ,假装已经过了足够的时间。

The call to jest.useFakeTimers() mocks every timer function with one that you must control. Instead of the timer running automatically, you would advance it manually. The jest.runTimersToTime(msToRun) function would advance it by msToRun milliseconds. It's very common that you want to fast-forward until every timer has elapsed and it would be cumbersome to calculate the time it takes for all the timers to finish, so Jest provides jest.runAllTimers(), which pretends that enough time has passed.

你的测试中的问题是你从不打电话给 jest.runAllTimers()测试,但你在 afterAll 钩子中调用它,在测试完成后称为。在测试期间,计时器保持为零,因此您的回调从未被实际调用过,并且Jest在预定义的时间间隔(默认值:5秒)后中止它,以防止陷入潜在的无限测试。只有在测试超时后,才调用 jest.runAllTimers(),此时它不会执行任何操作,因为所有测试都已完成。

The problem in your test is that you never call jest.runAllTimers() in the test, but you call it in the afterAll hook, which is called after the tests have finished. During your test the timer remains at zero so your callback is never actually called and Jest aborts it after a predefined interval (default: 5s) to prevent being stuck with a potentially endless test. Only after the test has timed out, you call jest.runAllTimers(), at which point it doesn't do anything, since all tests have already finished.

您需要做的是启动承诺,然后推进计时器。

What you need to do is launch the promise and then advance the timer.

describe('using a promise and mock timers', () => {
    test('gets a value, if conditions favor', () => {
        expect.assertions(1)
        // Keep a reference to the pending promise.
        const pendingPromise = withPromises(true)
            .then(resolved => {
                expect(resolved).toBe('something')
            })
        // Activate the timer (pretend the specified time has elapsed).
        jest.runAllTimers()
        // Return the promise, so Jest waits for its completion and fails the
        // test when the promise is rejected.
        return pendingPromise
    })
})

这篇关于使用带有Jest的setTimeout测试Promise的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆