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

如何在Next.js集成测试中Mock第三方API(如OpenAI)调用?

解决Next.js服务端API调用OpenAI时的Playwright Mock问题

问题背景

在Next.js的API路由中调用OpenAI API时,使用nock只能拦截浏览器端发起的请求,无法Mock服务端内部的API调用——因为测试代码里的nock运行在浏览器runtime,而服务端调用属于Node环境,拦截逻辑根本触达不到。直接在API路由里硬加nock虽然能生效,但会污染生产代码,不可取。

可行解决方案

方案1:通过环境变量切换OpenAI客户端实现

创建封装层隔离真实与Mock客户端,用环境变量控制加载逻辑,完全不侵入生产代码。

  1. 封装OpenAI客户端
    创建lib/openai.ts统一管理客户端实例:
// lib/openai.ts
import { OpenAI } from 'openai';

// 定义Mock客户端,对齐真实客户端的方法签名
class MockOpenAI {
  chat = {
    completions: {
      create: async () => ({
        choices: [
          {
            message: {
              content: 'Here is your AI query answer',
            },
          },
        ],
      }),
    },
  };
}

// 根据环境变量初始化对应客户端
const openaiClient = process.env.NODE_ENV === 'test'
  ? new MockOpenAI() as unknown as OpenAI
  : new OpenAI({ apiKey: process.env.OPENAI_API_KEY });

export default openaiClient;
  1. API路由使用封装客户端
// app/api/query/route.ts
import openaiClient from '@/lib/openai';

export async function GET() {
  const response = await openaiClient.chat.completions.create({
    model: 'gpt-3.5-turbo',
    messages: [{ role: 'user', content: 'Test query' }],
  });

  return Response.json({
    query: response.choices[0].message.content,
  });
}
  1. 测试环境配置
    在.env.test中添加NODE_ENV=test,Playwright启动时会自动加载Mock客户端。

方案2:启动测试服务时注入Nock拦截逻辑

通过自定义启动脚本,在Next.js服务启动前加载nock配置,让拦截逻辑运行在Node环境中,覆盖服务端的API请求。

  1. 创建Nock拦截脚本
    新建mock-openai.js:
// mock-openai.js
const nock = require('nock');

// 拦截OpenAI的实际接口路径(注意是POST请求)
nock('https://api.openai.com')
  .post('/v1/chat/completions')
  .reply(200, {
    choices: [
      {
        message: {
          content: 'Here is your AI query answer',
        },
      },
    ],
  });
  1. 添加测试专用启动脚本
    在package.json中新增脚本:
{
  "scripts": {
    "dev": "next dev",
    "test:dev": "NODE_ENV=test node -r ./mock-openai.js node_modules/.bin/next dev"
  }
}
  1. 修改Playwright配置
    更新playwright.config.ts中的webServer命令:
webServer: {
  command: 'pnpm run test:dev',
  url: baseURL,
  timeout: 120 * 1000,
  reuseExistingServer: !process.env.CI,
},

启动测试时,nock会在Node环境中提前加载,自动拦截服务端发起的OpenAI请求。


方案3:用本地Mock服务器替代真实API

使用msw启动本地Mock服务器,拦截服务端所有指向OpenAI的请求,适合复杂Mock场景。

  1. 安装依赖
pnpm add msw --save-dev
  1. 创建Mock处理器
    新建mocks/handlers.js:
// mocks/handlers.js
import { rest } from 'msw';

export const handlers = [
  rest.post('https://api.openai.com/v1/chat/completions', (req, res, ctx) => {
    return res(
      ctx.status(200),
      ctx.json({
        choices: [
          {
            message: {
              content: 'Here is your AI query answer',
            },
          },
        ],
      })
    );
  }),
];
  1. 启动Mock服务器脚本
    新建start-mock-server.js:
// start-mock-server.js
import { setupServer } from 'msw/node';
import { handlers } from './mocks/handlers';

const server = setupServer(...handlers);
server.listen();
console.log('OpenAI Mock server running');
  1. 更新测试启动脚本
{
  "scripts": {
    "test:dev": "NODE_ENV=test node start-mock-server.js & next dev"
  }
}

方案选择建议

  • 优先选方案1:逻辑清晰,完全隔离生产与测试代码,维护成本最低。
  • 快速验证选方案2:无需修改业务代码,仅通过启动脚本注入Mock逻辑。
  • 复杂Mock场景选方案3:支持动态返回、请求参数校验等高级功能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 16:15:55