在调用beforeEach()之前,异步beforeAll()不会完成 [英] Async beforeAll() does not finish before beforeEach() is called
问题描述
在Jest中, beforeAll()
应该在 beforeEach()
之前运行.
问题是,当我对 beforeAll()
使用异步回调时,Jest在继续进行 beforeEach()
之前不会等待回调完成.
如何强制Jest在继续进行 beforeEach()
之前等待异步 beforeAll()
回调完成?
最小的可复制示例
tests/myTest.test.js
const connectToMongo = require('../my_async_callback')//这使用异步回调.beforeAll(connectToMongo)//这是在beforeAll块完成之前输入的.=,(beforeEach(()=> {console.log('beforeEach的输入主体')}test('t1'),()=>{Expect(1).toBe(1)}test('t2'),()=>{Expect(2 + 2).toBe(4)}test('t3'),()=>{期望(3 + 3 + 3).toBe(9)}
my_async_callback.js
const connectToMongo = async()=>{尝试 {等待mongoose.connect(config.MONGODB_URI,{useNewUrlParser:是的,useUnifiedTopology:是的,useFindAndModify:false,useCreateIndex:true})console.log('已连接到MongoDB')} catch(err){console.log(`连接到MongoDB时出错:$ {err.message}`)}}module.exports = connectToMongo
更新:正如公认的答案所指出的那样,Jest实际上确实先等待 beforeAll
完成,除非Promise链断裂或超时.因此,我的问题的前提是错误的.我的 connectToMongo
函数正在超时,只需增加Jest超时即可解决此问题.
问题是,当我对
beforeAll()
使用异步回调时,Jest在继续进行beforeEach()
之前不会等待回调完成.如何强制Jest在继续进行
beforeEach()
之前等待异步beforeAll()
回调完成?
TLDR
简短的答案是,Jest 确实会先等待异步 beforeAll()
回调完成,然后再继续进行 beforeEach()
.>>
这意味着,如果 beforeEach()
在应在 beforeAll()
中运行的内容之前运行,则Promise链必须断开或 beforeAll
功能超时.
玩笑中的队列运行器
所有 如果 ...或者有超时(请注意,超时将由Jest在输出中报告): In Jest, The problem is that when I use an async callback for How can I force Jest to wait for an async tests/myTest.test.js my_async_callback.js UPDATE: As the accepted answer helpfully points out, Jest actually does wait for The problem is that when I use an async callback for How can I force Jest to wait for an async
The short answer is that Jest does wait for an async This means that if All of the So Jest starts with a resolved Promise and chains every function, in order, to the Promise chain with This behavior can be seen with the following test:
If
...or there is a timeout (note that the timeout will be reported by Jest in the output):
这篇关于在调用beforeEach()之前,异步beforeAll()不会完成的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! beforeAll
, beforeEach
, test
, afterEach
, afterAll
与测试关联的功能收集在 queueableFns
中,并链接为 破碎的承诺链
beforeEach
在应在 beforeAll
中运行的内容之前运行,则Promise链可能已损坏:
const order = [];//不返回Promise,并且会中断Promise链const func =()=>{setTimeout(()=> {order.push(2);},1000);}const asyncFunc = async()=>{order.push(1);等待func();//实际上并不等待2被推送order.push(3);}beforeAll(asyncFunc);beforeEach(()=> {order.push(4);});它(应按顺序运行",()=> {Expect(order).toEqual([1,2,3,4]);//失败:[1、3、4]});
超时
const order = [];jest.setTimeout(100);//100ms超时const asyncFunc = async()=>{order.push(1);等待新的Promise(resolve => {setTimeout(resolve,1000);});//超时order.push(2);}beforeAll(asyncFunc);beforeEach(()=> {order.push(3);});它(应按顺序运行",()=> {Expect(order).toEqual([1,2,3]);//失败:[1,3]和超时错误});
beforeAll()
is supposed to run before beforeEach()
.beforeAll()
, Jest doesn't wait for the callback to finish before going on to beforeEach()
.beforeAll()
callback to finish before proceeding to beforeEach()
?Minimal reproducible example
const connectToMongo = require('../my_async_callback')
// This uses an async callback.
beforeAll(connectToMongo)
// This is entered before the beforeAll block finishes. =,(
beforeEach(() => {
console.log('entered body of beforeEach')
}
test('t1'), () => {
expect(1).toBe(1)
}
test('t2'), () => {
expect(2+2).toBe(4)
}
test('t3'), () => {
expect(3+3+3).toBe(9)
}
const connectToMongo = async () => {
try {
await mongoose.connect(config.MONGODB_URI, {
useNewUrlParser: true,
useUnifiedTopology: true,
useFindAndModify: false,
useCreateIndex: true
})
console.log('Connected to MongoDB')
} catch (err) {
console.log(`Error connecting to MongoDB: ${err.message}`)
}
}
module.exports = connectToMongo
beforeAll
to finish first, except in the case of a broken Promise chain or a timeout. So, the premise of my question is false. My connectToMongo
function was timing out, and simply increasing the Jest timeout solved the problem.
beforeAll()
, Jest doesn't wait for the callback to finish before going on to beforeEach()
.beforeAll()
callback to finish before proceeding to beforeEach()
?TLDR
beforeAll()
callback to finish before proceeding to beforeEach()
.beforeEach()
is running before something that should run in beforeAll()
then the Promise chain must be broken or the beforeAll
function is timing out.
Queue Runner in Jest
beforeAll
, beforeEach
, test
, afterEach
, afterAll
functions associated with a test are collected in queueableFns
and are chained on these lines in queueRunner.ts: const result = options.queueableFns.reduce(
(promise, fn) => promise.then(() => mapper(fn)),
Promise.resolve(),
);
.then
.
const order = [];
// first beforeAll with async function
beforeAll(async () => {
order.push(1);
await new Promise((resolve) => { setTimeout(resolve, 1000); });
order.push(2);
});
// first beforeEach with done callback
beforeEach(done => {
order.push(4);
setTimeout(() => {
order.push(6);
done();
}, 1000);
order.push(5);
});
// second beforeEach
beforeEach(() => {
order.push(7);
});
// second beforeAll
beforeAll(() => {
order.push(3);
});
it("should run in order", () => {
expect(order).toEqual([1, 2, 3, 4, 5, 6, 7]); // SUCCESS!
});
Broken Promise Chain
beforeEach
is running before something that should run in beforeAll
then it is possible the Promise chain is broken:const order = [];
// does not return Promise and will break the Promise chain
const func = () => {
setTimeout(() => { order.push(2); }, 1000);
}
const asyncFunc = async () => {
order.push(1);
await func(); // doesn't actually wait for 2 to be pushed
order.push(3);
}
beforeAll(asyncFunc);
beforeEach(() => {
order.push(4);
});
it("should run in order", () => {
expect(order).toEqual([1, 2, 3, 4]); // FAIL: [1, 3, 4]
});
Timeout
const order = [];
jest.setTimeout(100); // 100ms timeout
const asyncFunc = async () => {
order.push(1);
await new Promise(resolve => { setTimeout(resolve, 1000); }); // times out
order.push(2);
}
beforeAll(asyncFunc);
beforeEach(() => {
order.push(3);
});
it("should run in order", () => {
expect(order).toEqual([1, 2, 3]); // FAIL: [1, 3] and Timeout error
});