Jest结合mongodb-memory-server时异步测试超时问题排查
Jest + Supertest 测试Express注册接口超时问题
我正在使用Jest和supertest测试一个Express应用,编写了以下两个测试用例:
- 传入正确的注册数据时,应创建并返回新用户
- 传入已注册的邮箱时,应返回409 Conflict错误
users.test.ts
import requests from "supertest"; import { MongoMemoryServer } from "mongodb-memory-server"; import mongoose from "mongoose"; import createServer from "../utils/createServer"; import User from "../models/User"; import { getRandomProfilePath } from "../utils/pathsGenerators"; const app = createServer(); let mongod: MongoMemoryServer; beforeAll(async () => { mongod = await MongoMemoryServer.create(); mongoose.connect(mongod.getUri()); }); afterAll(async () => { await mongoose.disconnect(); await mongoose.connection.close(); await mongod.stop(); }); const signUpData = { firstName: "john", lastName: "doe", email: "johndoe@gmail.com", password: "1234567890" }; const userDataForModel = { ...signUpData, profilePath: getRandomProfilePath() } describe("auth", () => { describe("sign-up", () => { describe("given all correct sign-up data", () => { // 这个测试用例正常工作 it("returns created user and token", async () => { const { body, statusCode, headers } = await requests(app) .post("/auth/sign-up") .send(signUpData); expect(headers["content-type"]).toMatch(/json/); expect(statusCode).toBe(201); expect(body.user).toBeDefined(); expect(body.token).toBeDefined(); }) }) describe("given user already exists", () => { it("returns 409", async () => { // 执行到这里后超时 await User.create(userDataForModel); // 下面的代码似乎无法执行 const { statusCode, body } = await requests(app) .post("/auth/sign-up") .send(signUpData) console.log(statusCode); console.log(body); expect(statusCode).toBe(409); expect(body.message).toBeDefined(); }) }) }) })
问题详情
第二个测试用例在调用await User.create(userDataForModel)后总是超时,后续代码无法执行。控制台显示User.create()实际触发了一个成功的HTTP请求:
::ffff:127.0.0.1 - - [15/Apr/2023:16:15:33 +0000] "POST /auth/sign-up HTTP/1.1" 201 700
已尝试的解决方法
- 使用
await requests(app)...替代User.create(userDataForModel) - 使用axios
- 改用
beforeAll()和afterAll()而非beforeEach()和afterEach() - 从
index.ts导入app,而非通过createServer()创建独立实例 - 使用
.then()替代async/await - 增加超时限制
createServer.ts
import express from "express"; import allRoutes from "../routes/index"; import globalMiddleware from "../middleware/globalMiddleware"; import notFound from "../middleware/notFound"; import errHandler from "../middleware/errHandler"; export default function createServer() { const app = express(); app.use(globalMiddleware); app.use(allRoutes); app.use(notFound); app.use(errHandler); return app; }
index.ts
import dotenv from "dotenv"; dotenv.config(); import "express-async-errors"; import connectDB from "./utils/connectDB"; import createServer from "./utils/createServer"; const PORT = process.env.PORT || 3000; const app = createServer(); app.listen(PORT, async () => { console.log(`app running on port ${PORT}`); await connectDB(); console.log("DB connected"); }) export default app;
核心需求
问题始终源于await User.create(userDataForModel),在第一个测试用例中运行它同样会超时。本质上需要找到一种在执行requests(app)前向数据库创建数据的方法,了解jest.fn()和jest.mock()但不清楚如何应用。
内容的提问来源于stack exchange,提问作者netrolite
相关产品推荐
相关产品推荐

