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

使用Jest测试Node.js API:如何无需启动服务即可测试接口端点

原生Node.js API免启动服务器测试方案

核心前提:拆分服务逻辑与启动代码

你首先要把服务逻辑和端口监听的代码拆开,大部分需要提前启动服务的情况,都是因为把http.createServer的实例化逻辑和listen监听端口的逻辑写在了同一个文件,且文件导入时就自动执行了listen方法。

示例修改如下:

原错误写法(app.js)

const http = require('http');
const server = http.createServer((req, res) => {
  // 你的路由处理逻辑
  if (req.url === '/api/test' && req.method === 'GET') {
    res.writeHead(200, {'Content-Type': 'application/json'})
    res.end(JSON.stringify({code: 0}))
    return
  }
  res.writeHead(404)
  res.end()
})

// 直接启动监听,导入文件就会占用端口
server.listen(3000, () => console.log('服务启动'))
module.exports = server

拆分后写法

  1. 服务逻辑文件app.js,仅导出服务实例,不执行监听:
const http = require('http');
const server = http.createServer((req, res) => {
  // 你的路由处理逻辑保持不变
  if (req.url === '/api/test' && req.method === 'GET') {
    res.writeHead(200, {'Content-Type': 'application/json'})
    res.end(JSON.stringify({code: 0}))
    return
  }
  res.writeHead(404)
  res.end()
})

module.exports = server
  1. 生产环境启动入口index.js,单独处理端口监听:
const server = require('./app')
server.listen(3000, () => console.log('服务启动'))

第二步:直接用supertest传入服务实例测试

supertest本身就支持直接传入http.Server实例,不需要你提前启动服务监听端口,它会内部处理请求模拟,不会占用实际端口。

测试文件示例app.test.js:

const request = require('supertest')
const server = require('./app')

// 所有测试跑完后关闭服务释放资源
afterAll(() => {
  server.close()
})

describe('API端点测试', () => {
  test('GET /api/test 返回正确结果', async () => {
    const res = await request(server).get('/api/test')
    expect(res.statusCode).toBe(200)
    expect(res.body.code).toBe(0)
  })

  test('不存在的路由返回404', async () => {
    const res = await request(server).get('/api/xxxx')
    expect(res.statusCode).toBe(404)
  })
})

可选优化

如果你的路由逻辑是抽成单独的处理函数的,也可以跳过supertest,直接构造模拟的req、res对象传入处理函数做单元测试,执行速度会更快。

内容的提问来源于stack exchange,提问作者EagleCanFly

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 13:30:00