Express单元测试报TypeError: app.address is not a function
Express单元测试
TypeError: app.address is not a function报错修复 核心诱因
你认为已经完成server实例导出的判断不成立,代码存在3个直接触发报错的问题:
- 导出语句位置错误:
module.exports = server写在export default声明的箭头函数内部,只有这个函数被主动调用时,这行赋值才会执行。直接require('./index')时,这行代码根本不会运行,不可能拿到server实例。 - 模块导出语法混用:同一份文件同时使用ES Module的
export default和CommonJS的module.exports,模块解析后require('./index')拿到的是包含default属性的模块对象,不是可被supertest识别的server/express实例,自然不存在*address()*方法。 - 核心初始化逻辑未执行:你声明的箭头函数需要接收
app入参才能执行挂载路由、启动监听的逻辑,但文件内既没有调用express()创建app实例,也没有主动调用这个导出的函数,app.listen从未运行,server实例根本没有被创建。
修复方案
1. 修正index.js初始化与导出逻辑
移除不必要的函数包裹,在模块顶层完成Express实例初始化、路由挂载、服务启动逻辑,统一使用CommonJS语法导出server实例,修改后完整代码如下:
import bodyParser from "body-parser"; import cookieParser from "cookie-parser"; import cors from "cors"; import express from "express"; import _ from "lodash"; import serveStatic from "serve-static"; const port = 8000; // 顶层初始化Express实例 const app = express(); app.use(express.json({ limit: "50mb" })); app.use( express.urlencoded({ extended: true }) ); app.use(bodyParser.json({ limit: "50mb" })); app.use(cors()); app.use(serveStatic("dist/", { index: ["index.html"] })); app.use(cookieParser()); if (_.isNil(process.env.APP_ENV)) { process.env.APP_ENV = "LOCAL"; } // ... 保留原有其他变量、业务逻辑 // 测试路由 app.get('/', function (req, res) { res.status(200).send('ok'); }); const server = app.listen(port, function () { // 修改变量名避免和外层port变量遮蔽 const listenPort = server.address().port; console.log('Example app listening at port %s', listenPort); }); // 顶层导出server实例 module.exports = server;
提示:如果需要保留初始化函数的封装形式,需要确保函数执行后返回server实例,且测试文件中调用该函数拿到返回值后再传入supertest,禁止把导出语句写在未执行的函数内部。
2. 测试文件适配(可选)
如果不需要在测试阶段启动真实端口监听,可以直接在index.js中导出app实例而非server实例传入supertest,能避免测试结束后端口占用问题,简化后的测试代码如下:
const request = require('supertest'); const app = require('./index'); describe('loading express', function () { it('responds to /', function testSlash(done) { request(app) .get('/') .expect(200, done); }); });
如果保留server实例导出的写法,原有测试代码中的beforeEach清除缓存、afterEach关闭服务的逻辑不需要调整,只要确保require('./index')拿到的是正确的server实例即可。
内容的提问来源于stack exchange,提问作者AnonymousAlias
相关产品推荐
相关产品推荐

