笑话:测试超时后拒绝的承诺

我正在尝试为这个函数的悲惨路径编写一个测试:


const awaitFirstStreamForPage = async page => {

  try {

    await page.waitForSelector('[data-stream="true"]', {

      timeout: MAX_DELAY_UNTIL_FIRST_STREAM,

    })

  } catch (e) {

    throw new Error(`no stream found for ${MAX_DELAY_UNTIL_FIRST_STREAM}ms`)

  }

}

我设法编写了一个通过的测试,但它需要 10 秒才能运行,因为它实际上是在等待测试完成。


describe('awaitFirstStreamForPage()', () => {

  it('given a page and no active stream appearing: should throw', async () => {

    jest.setTimeout(15000)


    const browser = await puppeteer.launch({ headless: true })

    const page = await getPage(browser)


    let error


    try {

      await awaitFirstStreamForPage(page)

    } catch (err) {

      error = err

    }


    const actual = error.message

    const expected = 'no stream found for 10000ms'


    expect(actual).toEqual(expected)


    await browser.close()

    jest.setTimeout(5000)

  })

})

可能有一种方法可以使用 Jest 的假计时器来解决它,但我无法让它工作。这是我最好的尝试:


const flushPromises = () => new Promise(res => process.nextTick(res))


describe('awaitFirstStreamForPage()', () => {

  it('given a page and no active stream appearing: should throw', async () => {

    jest.useFakeTimers()


    const browser = await puppeteer.launch({ headless: true })

    const page = await getPage(browser)


    let error


    try {

      awaitFirstStreamForPage(page)

      jest.advanceTimersByTime(10000)

      await flushPromises()

    } catch (err) {

      error = err

    }


    const actual = error.message

    const expected = 'no stream found for 10000ms'


    expect(actual).toEqual(expected)


    await browser.close()

    jest.useRealTimers()

  })

})

失败并抛出


(node:9697) UnhandledPromiseRejectionWarning: Error: no stream found for 10000ms

即使我将失败的函数包装在一个try/catch. 你如何使用假计时器测试这样的功能?


白衣染霜花
浏览 66回答 2
2回答

MMTTMM

如果不等待,就不可能从awaitFirstStreamForPage(page)with 中捕捉到拒绝。try..catch拒绝应该被捕获但是在调用之后advanceTimersByTime并且可能在 之后flushPromises。有可能:const promise = awaitFirstStreamForPage(page);promise.catch(() => { /* suppress UnhandledPromiseRejectionWarning */ });jest.advanceTimersByTime(10000)await flushPromises();await expect(promise).rejects.toThrow('no stream found for 10000ms');

慕森王

问题似乎不是假计时器的使用:您预期的错误是被抛出的错误。但是,在 Jest 中测试抛出错误的函数时,您应该将抛出错误的代码包装在一个函数中,如下所示:expect(()=> {/* code that will throw error */}).toThrow()更多细节在这里: https: //jestjs.io/docs/en/expect#tothrowerror编辑:对于异步函数,你应该使用rejectsbefore toThrow;看这个例子:Can you write async tests that expect toThrow?
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript