我现在花了一些时间尝试在 Jest 测试中查找内存泄漏,尽管我已经成功解决了一些问题,但仍然有相当多的内存在测试套件之间泄漏。具体来说,当我npm test
(所有测试套件),我得到以下输出:
PASS src/.../suite1.test.ts (71.154 s, 163 MB heap size)
PASS src/.../suite2.test.ts (59.809 s, 229 MB heap size)
PASS src/.../suite3.test.ts (9.838 s, 231 MB heap size)
PASS src/.../suite4.test.ts (7.696 s, 242 MB heap size)
FAIL src/.../suite5.test.ts (251 MB heap size)
PASS src/.../suite6.test.ts (10.825 s, 318 MB heap size)
PASS src/.../suite7.test.ts (19.679 s, 363 MB heap size)
PASS src/.../suite8.test.ts (14.128 s, 408 MB heap size)
PASS src/.../suite9.test.ts (16.89 s, 452 MB heap size)
从上面的输出来看,测试套件完成后似乎仍有一些东西仍然存在。到底是什么困扰着我!内存泄漏似乎也可能在所有测试套件之间共享,因为每个套件都比上一个套件留下了更多的内存堆大小。
这是我所有测试套件的共享测试结构:
import request from "supertest";
import app from "../../app";
import mongoose from "mongoose";
...
some models that I need for testing
...
import faker from "faker";
import eventEmitter from "../../loaders/eventEmitter";
jest.mock("../../some-module");
jest.mock("../../another-module");
jest.mock("axios", () => {
// Require the original module to not be mocked...
const originalModule = jest.requireActual("axios");
return {
...originalModule,
post: jest.fn().mockReturnValue({ data: { access_token: 123, expires_in: 600000 } })
};
});
describe("TestSuite1", () => {
beforeEach(() => jest.clearAllMocks());
beforeAll(async () => await connectDb("TestSuite1"));
afterEach(async () => await clearDb()); // Function that deletes collections from Mongo
afterAll(async () => {
await mongoose.connection.dropDatabase();
await mongoose.connection.close();
});
describe("POST /some-endpoint") {
beforeEach(async () => {
myDocument = await buildDocument(); // Builds and saves() to Mongo some document
});
it("some assertion", async () => {
const response = await request(app)
.post("some-endpoint")
.send(some-data)
.set("Accept", "application/json");
expect(response.status).toEqual(204);
// more assertions on the response
});
}
这里有什么显而易见的事情吗?如果需要,我可以添加更多代码。
Edit:当我使用 --detectOpenHandles 运行测试时,我也会收到此错误;这可能相关吗?
● TCPSERVERWRAP
108 | it("some assertion", async () => {
109 | const response = await request(app)
> 110 | .post("some-endpoint")
| ^
111 | .send({})
112 | .set("some-header", header-value)
113 | .set("Accept", "application/json");
Edit 2:我尝试在测试套件之后关闭服务器,添加以下内容:
let server: http.Server;
let agent: SuperAgentTest;
beforeAll(async () => {
await connectDb("TestSuite1");
server = app.listen(4000, () => {
agent = request.agent(server);
});
});
afterAll(async () => {
await closeDb();
jest.resetAllMocks();
server && server.close();
});
这似乎解决了打开句柄问题,但没有解决内存泄漏问题。
另外,为了清楚起见,eventEmitter
导入的模块执行以下操作:
const eventEmitter = new EventEmitter();
export default eventEmitter;