如何阻止Jest在globalSetup未完成时执行测试?
问题场景
我用Jest的globalSetup创建DynamoDB表,globalTeardown销毁表,代码仅调用通用的dynamodb.createTable()和dynamodb.deleteTable()方法。
基础测试代码如下:
describe('Test suite', () => { beforeAll(async () => { await InsertEntity() }) test('test', async () => { const response = await getEntities() expect(response.success).toBe(true) }) })
插入实体的代码:
export const InsertEntities = async () => { const entity = new Entity({ // some data }) const result = await entity.save() console.log('entity', result) }
问题是Jest会在DynamoDB表创建完成前就执行测试,导致失败。我已经试过这些方案:
- 用
--runInBand参数运行Jest - 设置
jest.setTimeout()为不同时长(最长20秒) - 将
beforeAll改为beforeEach - 确认表创建所需时间为10秒
- 改成
setupFilesAfterEnv模式,但测试还是崩溃
之前类似代码能正常运行,现在不行,想知道Jest执行流程里遗漏了什么。
解决方案
核心问题是**globalSetup里的createTable只是发起了创建请求,没等表完全就绪就结束了**。DynamoDB的createTable是异步操作,调用后会立即返回,但表要从CREATING状态变为ACTIVE才能正常读写,你这次的代码漏了等待表激活的逻辑。
1. 在globalSetup里等待表完全激活
修改你的globalSetup代码,在调用createTable后,轮询检查表状态,直到它变为ACTIVE:
// globalSetup.js const { DynamoDBClient, CreateTableCommand, DescribeTableCommand } = require("@aws-sdk/client-dynamodb"); module.exports = async () => { const dynamodb = new DynamoDBClient({/* 你的配置 */}); // 发起创建表请求 await dynamodb.send(new CreateTableCommand({/* 表结构参数 */})); // 轮询等待表激活 const waitForTableActive = async () => { try { const response = await dynamodb.send(new DescribeTableCommand({ TableName: "你的表名" })); if (response.Table.TableStatus === "ACTIVE") return; } catch (err) { // 表未创建完成时会抛出ResourceNotFoundException,忽略继续等待 if (err.name !== "ResourceNotFoundException") throw err; } // 间隔1秒后重试 await new Promise(resolve => setTimeout(resolve, 1000)); await waitForTableActive(); }; await waitForTableActive(); };
2. 确保globalSetup的异步逻辑完全完成
Jest的globalSetup要求导出的异步函数必须等待所有异步操作完成,才会进入测试阶段。检查你的globalSetup代码:
- 调用
dynamodb.createTable()时必须加await - 不能用回调式的异步逻辑,必须用Promise或async/await包裹所有异步步骤
3. 排查setupFilesAfterEnv的问题
setupFilesAfterEnv是每个测试文件执行前都会运行,如果把表创建逻辑放在这里,会导致重复创建表引发错误。正确的做法还是用globalSetup创建表,setupFilesAfterEnv只处理测试前的通用准备(比如插入测试数据)。
4. 用AWS SDK自带的等待方法(可选)
如果用AWS SDK v2,可以直接用waitFor方法省去手动轮询:
const AWS = require('aws-sdk'); const dynamodb = new AWS.DynamoDB(); await dynamodb.waitFor('tableExists', { TableName: '你的表名' }).promise();
内容的提问来源于stack exchange,提问作者tolleration
相关产品推荐
相关产品推荐

