使用Jest和Supertest测试Express服务端点时遭遇TypeError: app.address is not a function错误
解决Jest+Supertest测试Express时的
TypeError: app.address is not a function错误 这个错误的核心原因是你传给Supertest的是已经调用listen()后的HTTP Server实例,而不是原始的Express app实例。Supertest需要直接操作Express的app对象来启动临时测试服务器,而非已经绑定端口的server对象。
解决方案1:直接在测试中导入Express app实例
修改你的integration.test.ts,直接从src/app.ts导入app,替代从server.ts导入已启动的server:
// backend/tests/integration.test.ts import supertest from 'supertest'; import app from '../src/app'; // 直接导入app实例,而非server const appTest = supertest(app); describe('Integration tests', () => { it('GET /api/ping', async () => { const expected = { status: 200, body: { success: true } } const res = await appTest.get('/api/ping'); expect(res.status).toEqual(expected.status); expect(res.body).toEqual(expected.body); }); });
解决方案2:调整server.ts的导出(可选)
如果你希望保留从server.ts导入的习惯,可以在server.ts中同时导出app和server:
// backend/server.ts import app from './src/app'; const PORT = 3000; const server = app.listen(PORT, () => { console.log(`Server running on port ${PORT}`); }); export { server, app }; // 同时导出server和app
然后在测试文件中导入app:
// backend/tests/integration.test.ts import supertest from 'supertest'; import { app } from '../server'; const appTest = supertest(app); // 测试代码保持不变...
额外注意事项
- 你的代码混合了CommonJS(
require)和ES模块(import/export)语法,在TS项目中建议统一使用ES模块语法,避免模块交互问题。 - 确保你的Jest配置正确处理TS模块,当前的
jest.config.js看起来没问题,且你的tsconfig已开启esModuleInterop,Jest会继承这个配置来处理模块兼容。
这样修改后,Supertest就能正确获取Express app的address方法,启动临时测试服务器,你的测试应该就能正常运行了。
内容的提问来源于stack exchange,提问作者Sami
相关产品推荐
相关产品推荐

