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

nock/msw拦截器在GitHub Actions失效但本地正常,如何修复?

解决GitHub Actions中nock/msw测试报错:Cannot set property request of [object Object] which has only a getter

本地使用nock和msw进行API测试均正常,但在GitHub Actions中运行测试时,两个库都抛出相同的TypeError: Cannot set property request of [object Object] which has only a getter错误。

报错详情

nock 报错日志

FAIL src/CustomHeader.test.ts
  ● Test suite failed to run

    TypeError: Cannot set property request of [object Object] which has only a getter

      at node_modules/nock/lib/common.js:95:20
          at Array.forEach (<anonymous>)
      at Object.overrideRequests (node_modules/nock/lib/common.js:71:22)
      at activate (node_modules/nock/lib/intercept.js:373:10)
      at Object.setup (node_modules/nock/lib/back.js:115:5)
      at Function.Object.<anonymous>.Back.setMode (node_modules/nock/lib/back.js:330:9)
      at Object.<anonymous> (node_modules/nock/index.js:52:8)

msw 报错日志

FAIL src/CustomHeader.test.ts
  ● Client request() with custom header › Valid additional header

    TypeError: Cannot set property request of [object Object] which has only a getter

      12 |
      13 | describe('Client request() with custom header', () => {
    > 14 |   beforeAll(() => server.listen());
         |                          ^
      15 |   afterEach(() => server.resetHandlers());
      16 |   afterAll(() => server.close());
      17 |

      at _loop_1 (node_modules/@mswjs/interceptors/src/interceptors/ClientRequest/index.ts:67:28)
      at ClientRequestInterceptor.Object.<anonymous>.ClientRequestInterceptor.setup (node_modules/@mswjs/interceptors/lib/interceptors/ClientRequest/index.js:106:17)
      at ClientRequestInterceptor.Object.<anonymous>.Interceptor.apply (node_modules/@mswjs/interceptors/src/Interceptor.ts:127:10)
      at _loop_1 (node_modules/@mswjs/interceptors/src/BatchInterceptor.ts:43:19)
      at BatchInterceptor.Object.<anonymous>.BatchInterceptor.setup (node_modules/@mswjs/interceptors/lib/BatchInterceptor.js:58:17)
      at BatchInterceptor.Object.<anonymous>.Interceptor.apply (node_modules/@mswjs/interceptors/src/Interceptor.ts:127:10)
      at Object.listen (node_modules/msw/src/node/createSetupServer.ts:122:21)
      at src/CustomHeader.test.ts:14:26

测试代码片段

msw 测试代码

import { rest, RestContext } from 'msw';
import { setupServer } from 'msw/node';

const mockBody = { test: 'result' };
const server = setupServer(rest.get('https://localhost/path', (_: never, res: any, ctx: RestContext) => res(ctx.status(200), ctx.json(mockBody))));

describe('Client request() with custom header', () => {
  beforeAll(() => server.listen());
  afterEach(() => server.resetHandlers());
  afterAll(() => server.close());

  test('Valid additional header', async () => {
    const client = new Client(PROXY_HOST, API_KEY);
    const customHeaders = {
      'test-header': 'test-value',
    };

    const input = ['GET', '/path', 'query=string', 'body'];
    const event = getAPIGatewayProxyEvent(input);
    const response = await client.request(event, customHeaders);
    expect(response).toStrictEqual({
      body: JSON.stringify({ test: 'result' }),
      headers: {
        'content-type': 'application/json',
        'test-header': 'test-value',
      },
      statusCode: 200,
    });
  });
});

nock 测试代码

describe('Client request() with custom header', () => {
  afterEach(() => nock.cleanAll());

  test('Valid additional header', async () => {
    nock('https://localhost')
      .get('/path')
      .query(true) // Ignores query string
      .reply(200, { test: 'result' });
    const client = new Client(PROXY_HOST, API_KEY);
    const customHeaders = {
      'test-header': 'test-value',
    };

    const input = ['GET', '/path', 'query=string', 'body'];
    const event = getAPIGatewayProxyEvent(input);
    const response = await client.request(event, customHeaders);
    expect(response).toStrictEqual({
      body: JSON.stringify({ test: 'result' }),
      headers: {
        'content-type': 'application/json',
        'test-header': 'test-value',
      },
      statusCode: 200,
    });
  });
});

解决方案

这个错误的核心原因是测试库版本与GitHub Actions中使用的Node.js版本不兼容,或者环境中存在修改http模块的冲突逻辑。可以按以下步骤修复:

  1. 统一Node.js版本
    在GitHub Actions的工作流文件(如.github/workflows/test.yml)中,明确指定与本地测试一致的Node.js版本,避免版本差异导致的API变化:

    - name: Setup Node.js
      uses: actions/setup-node@v4
      with:
        node-version: '18' # 替换成你本地使用的版本,比如16/20
        cache: 'npm'
    
  2. 升级测试库到兼容版本

    • 对于nock:升级到v13.x及以上版本(该版本开始支持Node.js 18+的只读request属性),执行命令:
      npm install nock@latest --save-dev
      
    • 对于msw:升级到v2.x及以上版本,同时确保@mswjs/interceptors也更新到兼容版本,执行命令:
      npm install msw@latest --save-dev
      
  3. 强制覆盖拦截器(针对msw)
    如果升级后仍有问题,可以在server.listen()时添加force: true选项,强制覆盖现有请求拦截逻辑:

    beforeAll(() => server.listen({ force: true }));
    
  4. 检查环境代理设置
    GitHub Actions的Ubuntu runner默认可能存在代理配置,可在工作流中添加环境变量禁用代理:

    env:
      NO_PROXY: localhost,127.0.0.1
      HTTP_PROXY: ""
      HTTPS_PROXY: ""
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 23:27:27