如何使用Jest为npm request.post编写单元测试并配置Mock?
Jest 封装 request.post 方法的单元测试实现
基础Mock配置
首先需要在测试文件中全局Mock request 模块,避免触发真实网络请求,让所有交互完全可控:
- 在测试文件顶部添加
jest.mock('request'),Jest会自动将模块所有方法替换为可追踪的Mock函数 - 导入被Mock的
request模块、以及你封装好的返回Promise的POST请求方法,用于后续断言和调整Mock行为 - 每个测试运行前清空所有Mock的调用记录,避免不同用例间的状态互相污染
基础代码框架:
jest.mock('request'); const request = require('request'); // 导入你自己封装的POST请求方法(即返回Promise、内部调用request.post的那个方法) const { postRequest } = require('./你的请求封装文件路径'); beforeEach(() => { jest.clearAllMocks(); });
分场景实现测试覆盖
场景1:请求抛出错误(error回调触发)
- 测试逻辑:手动构造触发error的回调参数,断言封装方法会正确将error作为reject值返回
代码实现:
test('请求发生网络错误时应正确reject对应error', async () => { // 构造模拟的错误对象 const mockNetworkError = new Error('网络连接超时'); // 重写request.post的Mock实现:收到请求配置后,直接触发回调,传入我们预设的error request.post.mockImplementation((reqConfig, callback) => { callback(mockNetworkError, {}, ''); }); // 断言封装方法的Promise会被reject,且错误对象匹配 await expect(postRequest({ url: 'https://test.com/api' })).rejects.toThrow(mockNetworkError); });
场景2:响应statusCode非200
- 测试逻辑:构造不带error、但状态码非200的响应参数,断言封装方法会返回对应格式的错误信息
代码实现:
test('响应状态码非200时应正确reject状态错误', async () => { // 构造模拟的非200响应 const mockBadResponse = { statusCode: 500 }; request.post.mockImplementation((reqConfig, callback) => { // error传null,传入构造的响应,body值无意义(逻辑中状态码不匹配时不会走到解析步骤) callback(null, mockBadResponse, ''); }); // 断言reject的内容和封装代码中拼接的错误字符串完全一致 await expect(postRequest({ url: 'https://test.com/api' })).rejects.toBe('Invalid status code <500>'); });
场景3:请求成功流程
- 测试逻辑:构造状态码200、合法JSON字符串格式的响应体,断言封装方法会正确解析JSON并返回对应结果,同时校验请求配置是否正确传给了底层
request.post
代码实现:
test('请求成功时应正确resolve解析后的响应数据', async () => { // 构造模拟的成功响应参数 const mockResponseData = { code: 0, message: 'success', data: { id: 1 } }; const mockSuccessResponse = { statusCode: 200 }; const testReqConfig = { url: 'https://test.com/api', form: { name: 'test' } }; request.post.mockImplementation((reqConfig, callback) => { callback(null, mockSuccessResponse, JSON.stringify(mockResponseData)); }); // 断言方法会正确resolve解析后的JSON对象 await expect(postRequest(testReqConfig)).resolves.toEqual(mockResponseData); // 额外校验:底层request.post确实收到了我们传入的请求配置 expect(request.post).toHaveBeenCalledWith(testReqConfig, expect.any(Function)); });
实现说明
- 由于
request库的回调签名是(error, response, body),所有Mock实现都是按照这个签名手动触发回调,完全绕过真实的网络请求逻辑。 - 每个测试用例的参数都是完全可控的,不需要依赖外部服务环境。
- 如果需要额外覆盖响应JSON格式不合法的场景,可以在成功状态码的分支下,传入非JSON格式的body字符串,断言
JSON.parse抛出的错误会被正确reject。
内容的提问来源于stack exchange,提问作者Bikesh M
相关产品推荐
相关产品推荐

