在我的Express.js开玩笑测试中找不到内存泄漏
现在,我花了一些时间试图在玩笑测试中找到内存泄漏,即使我成功解决了一些测试,但仍有很多内存从测试套件泄漏到测试套件。具体来说,当i npm测试
(所有测试套件)时,我将获得以下输出:
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
});
}
这里有什么明显的吗?如果需要,我可以添加更多代码。
编辑: 当我使用-Dectopenhandles进行测试时,我也会得到此错误;可能是相关的吗?
● 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");
编辑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;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
让我们尝试分析一些事情:
查看您的代码,我无法立即确定一个问题(这是我很久以前遇到的事情,但并没有太多地挖掘出来)。
我考虑了一点,我认为,唯一的其他可能性是 - 这不是您的错,这可能是Jest's垃圾收藏的问题。
在。
我建议使用
-runinband
进行测试以查看使用/没有它的统计数据(即jest-logheapusage -runinband
)。此外,如上述问题所示,尝试使用
- expose-gc
露出垃圾收集器,并添加到公共测试设置中,以确保强制垃圾收集。
Let's try to analyze things a little bit:
Looking at your code, I couldn't identify an issue right away (it's something I've also ran into a long time ago but didn't dig into too deply).
I thought about it a little more and in my opinion, the only other possibility is - it's not your fault and could be an issue with jest's garbage collection.
There has been discussion around this in https://github.com/facebook/jest/issues/7874.
I'd recommend running the test with
--runInBand
to see stats with/without it (i.e.jest --logHeapUsage --runInBand
).Additionally, as seen in the workaround in the issue above, try exposing the garbage collector with
--expose-gc
and addingto the common test setup to ensure garbage collection is forced.