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
相关产品推荐
相关产品推荐

