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

Node.js环境下使用Jest Mock多个HTTPS POST请求的方法咨询

多HTTPS请求场景的Jest Mock方案

问题根源

你当前的实现存在三个核心问题:

  • statusCode属性被错误定义为Mock函数:Node.js原生https响应的statusCode是普通数值属性,不是可执行函数,你在Mock中将其设置为jest.fn(),业务代码直接访问属性时自然会拿到函数本身,而非执行后的返回值。
  • 依赖加载顺序错误:你先require了业务代码,再对https模块做Mock,业务代码加载时已经拿到了原生https实例,Mock逻辑不会生效。
  • 没有按请求顺序动态返回不同响应:原Mock逻辑固定返回同一套响应配置,无法区分两次不同的接口请求。

正确实现方案

调整后的测试用例代码如下:

test('2nd API Errors', async() => {
    let decodedJson = {            
        keyValue: '0001b3f6-7754-4dcb-891e-someTestdata'
    };
    jest.doMock('../CommonFiles/jwtDecoder', () => (res, req, cb) => cb(null, decodedJson));

    // 1. 先配置数据库Mock
    jest.mock('tedious', () => ({
        ...jest.requireActual('tedious'),
        Connection: jest.fn(() => ({
            connect: () => {},
            on: (connect, cb) => cb(),
            close: () => {},
            execSql: () => {}
        })),
        TYPES: jest.fn(),
        Request: jest.fn(() => ({
            constructor: (sqlString, cb) => cb('err', null, null),
            addParameter: (name, type, value) => {},
            on: (requestCompleted, cb) => cb('rowCount', 'more')
        }))
    }));

    // 2. 定义两次请求的对应返回配置,按调用顺序排列
    const mockResponses = [
        // 第一个请求:getMobileNo接口返回
        {
            statusCode: 200,
            body: JSON.stringify({
                resolvedTokens: [{ phone: "1234" }],
                unresolvedTokens: []
            }),
            statusMessage: 'OK'
        },
        // 第二个请求:sendSMS接口返回
        {
            statusCode: 400,
            body: JSON.stringify({}),
            statusMessage: '2nd API failed'
        }
    ]

    // 3. Mock https模块,按调用顺序返回对应响应
    var https = require('https');
    jest.mock('https', () => ({
        ...jest.requireActual('https'),
        request: jest.fn((postOption, cb) => {
            // 按调用次数取对应响应配置
            const callIndex = jest.mocked(https.request).mock.calls.length - 1
            const currentRes = mockResponses[callIndex]
            // 构造符合规范的响应对象
            const res = {
                setEncoding: jest.fn(),
                on: (event, cb) => {
                    if (event === 'data') cb(Buffer.from(currentRes.body, 'utf8'))
                    if (event === 'end') cb()
                },
                statusCode: currentRes.statusCode,
                statusMessage: currentRes.statusMessage
            }
            cb(res)
            // 返回request实例必要方法
            return {
                write: jest.fn(),
                end: jest.fn(),
                on: jest.fn()
            }
        })
    }))

    // 4. 所有Mock完成后再引入业务代码
    let httpFunction = require('../SMSHttpFunction/index')

    let request = {
        body: "test.jwt.secret"
    };

    // 生成context对象
    const context = await runStubFunctionFromBindings(httpFunction, [
        { type: 'httpTrigger', name: 'req', direction: 'in', data: request },
        { type: 'http', name: 'res', direction: 'out' },
    ], new Date());
    console.log('context.res:->', context.res);
    expect(context.res.status).toEqual(400);
    // 业务代码返回的body为字符串,调整断言匹配实际逻辑
    expect(context.res.body).toBe('Problem in API 2');
})

注意事项

  • 所有jest.mock调用必须早于业务代码的require操作,否则Mock不会生效。
  • 如果需要根据请求URL/参数区分返回值,可在requestMock的回调中读取postOption的host、path等属性,匹配对应接口返回指定配置,适配更多复杂场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 07:36:03