You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 13:06:24