gpt4 book ai didi

node.js - 异步 beforeAll() 在 beforeEach() 被调用之前没有完成

转载 作者:行者123 更新时间:2023-12-04 11:54:03 25 4
gpt4 key购买 nike

在 Jest 中,beforeAll()应该在 beforeEach() 之前运行.
问题是当我对 beforeAll() 使用异步回调时, Jest 不会等待回调完成才继续 beforeEach() .
如何强制 Jest 等待异步 beforeAll()在继续之前回调完成 beforeEach() ?
最小的可重复示例
测试/myTest.test.js

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)
}
my_async_callback.js
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
更新:正如公认的答案所指出的那样,Jest 实际上确实在等待 beforeAll首先完成,除非 Promise 链损坏或超时。所以,我的问题的前提是错误的。我的 connectToMongo功能超时,只需增加 Jest 超时即可解决问题。

最佳答案

The problem is that when I use an async callback for beforeAll(), Jest doesn't wait for the callback to finish before going on to beforeEach().

How can I force Jest to wait for an async beforeAll() callback to finish before proceeding to beforeEach()?


TLDR
简短的回答是 Jest 等待异步 beforeAll()在继续之前回调完成 beforeEach() .
这意味着如果 beforeEach()在应该运行的东西之前运行 beforeAll()那么 Promise 链必须被破坏,否则 beforeAll功能超时。

Jest 中的队列运行器
所有的 beforeAll , beforeEach , test , afterEach , afterAll与测试相关的函数收集在 queueableFns 中并被链接 on these lines in queueRunner.ts :
  const result = options.queueableFns.reduce(
(promise, fn) => promise.then(() => mapper(fn)),
Promise.resolve(),
);
因此,Jest 从一个已解析的 Promise 开始,并按顺序将每个函数链接到带有 .then 的 Promise 链。 .

可以通过以下测试看到此行为:
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!
});


splinter 的 promise 链
beforeEach在应该运行的东西之前运行 beforeAll那么有可能 Promise 链被破坏了:
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]
});

暂停
...或者有超时(请注意,超时将在输出中由 Jest 报告):
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
});

关于node.js - 异步 beforeAll() 在 beforeEach() 被调用之前没有完成,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66193832/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com