2017-10-12 32 views
1

我试图了解Jest的异步测试。使用setTimeout测试Promise

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

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 } 

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

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') 
      }) 
    }) 
}) 

我碰到下面的错误/失败测试,​​是否我叫​​

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

您能否解释我要出错的地方,以及我可能做些什么来获得通过测试,以便按照预期的方式解决问题?

回答

3

致电jest.useFakeTimers()嘲笑每一个定时器功能,你必须必须控制。而不是自动运行计时器,您可以手动提前。 jest.runTimersToTime(msToRun)函数会提前msToRun毫秒。这是很常见的,你想快速前进,直到每个计时器已经过去,并且计算所有计时器完成所需的时间会很麻烦,所以Jest提供了jest.runAllTimers(),这表明已经有足够的时间过去了。

在测试的问题是,你永远不会调用​​的测试,但你怎么称呼它在afterAll钩,这就是所谓后的测试已经完成。在测试期间,计时器保持为零,因此实际上不会调用回调函数,Jest会在预定义的时间间隔(默认值:5秒)后中止它以防止被潜在的无尽测试卡住。只有在测试超时后,您才能拨打​​,此时它不会执行任何操作,因为所有测试都已完成。

你需要做的是启动承诺,然后提前计时器。

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 
    }) 
}) 
+0

This Works!非常感谢解释和解释和代码示例。 –

相关问题