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

使用Jest与nock进行HTTP模拟:Next.js接口测试失效问题排查

解决你的Next.js API路由Jest测试问题

我完全理解你现在的困惑——第一次写测试遇到这种“怎么改都通过”的情况确实让人头大!先直接点出核心问题:你的测试只是设置了nock的拦截,但从来没有实际调用你要测试的/api/weather接口,也没有任何断言逻辑。Jest默认只要测试函数里没抛出错误,就会标记为通过,哪怕你啥实际测试都没做。

接下来一步步帮你搞定正确的测试:

第一步:安装必要的依赖

你需要用supertest来模拟对Next.js API路由的HTTP请求,先安装它:

npm install supertest --save-dev

第二步:完整的测试用例(带注释)

下面是修正后的测试代码,每一步都标注了作用:

import request from 'supertest';
import nock from 'nock';
// 导入你的API路由处理函数
import handler from '../pages/api/weather';

// 测试前先设置固定的环境变量,避免依赖本地.env文件
beforeAll(() => {
  process.env.WEATHER_API_KEY = 'test-key-123';
});

// 测试外部API成功时的场景
it('should return weather data when external API succeeds', async () => {
  // 1. 用nock拦截外部API的请求
  nock('https://api.weatherapi.com')
    .get('/v1/current.json')
    // 匹配查询参数:key用我们设置的测试key,city是London
    .query({ key: 'test-key-123', q: 'London' })
    // 模拟外部API返回成功数据(和真实API结构对齐)
    .reply(200, { current: { temp_c: 18 } });

  // 2. 用supertest调用我们自己的API路由
  const response = await request(handler)
    .get('/') // Next.js API路由测试中,路径用/对应/api/weather
    .query({ city: 'London' }); // 传递查询参数

  // 3. 添加断言,验证结果是否符合预期
  expect(response.status).toBe(200);
  expect(response.body.current.temp_c).toBe(18);
});

// 测试外部API失败时的场景
it('should return 400 error when external API fails', async () => {
  // 拦截外部API,模拟返回400错误
  nock('https://api.weatherapi.com')
    .get('/v1/current.json')
    .query({ key: 'test-key-123', q: 'InvalidCity' })
    .reply(400);

  // 调用我们的API
  const response = await request(handler)
    .get('/')
    .query({ city: 'InvalidCity' });

  // 断言响应状态和错误信息
  expect(response.status).toBe(400);
  expect(response.body.message).toBe('Currently not avaliable'); // 注意和你代码里的拼写保持一致
});

// 测试后清理nock拦截,避免影响其他用例
afterEach(() => {
  nock.cleanAll();
});

关键问题拆解

1. 为什么之前测试总是通过?

你之前的代码只做了nock拦截,但没有触发任何实际请求,也没有写expect断言。Jest的逻辑是“没有抛出错误就是测试通过”,所以不管你改nock的状态码还是返回值,测试都会直接通过。只有当你调用API并添加断言后,不符合预期的情况才会让测试失败。

2. nock的正确打开方式

  • 不用把完整的查询字符串硬编码在get路径里,用.query()方法匹配更灵活,也避免了硬编码API key的问题。
  • 要确保nock拦截的域名、路径和你API代码里的完全一致(原代码里是https://api.weatherapi.com/v1/current.json,所以nock的域名是https://api.weatherapi.com,路径是/v1/current.json)。

3. Next.js API路由的测试逻辑

  • 用supertest直接导入你的handler函数,模拟前端发起的HTTP请求。
  • 传递查询参数用.query()方法,和你前端实际调用的方式完全对齐。

额外注意事项

  • 你原代码里的错误信息拼写是avaliable(少了一个l),断言时要和代码里的拼写保持一致,不然会失败。
  • 外部WeatherAPI的真实返回结构是{ current: { ... } },不是你之前测试里写的results,要和真实接口结构匹配。
  • 测试时固定环境变量,避免依赖本地的.env文件,保证测试的可重复性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 11:27:32