如何用Jest模拟messaging-api-messenger的sendBatch方法并指定返回值?
如何用Jest正确模拟messaging-api-messenger的sendBatch方法并返回指定值
我想在单元测试中用Jest模拟第三方包messaging-api-messenger里的sendBatch方法,当前代码模拟不生效,实际返回400结构的结果,我需要让它返回指定的200结构结果。
原代码
sendMessages.js
async function sendMessage () { const { MessengerClient } = require('messaging-api-messenger') const client = new MessengerClient({accessToken: 'accessToken'}) return client.sendBatch([{message:'message', to:'someone'}]) } module.exports = sendMessage() // 核心问题:直接导出函数执行结果,而非函数本身
send.test.js
const Send = require('./sendMessage') const sendBatchMock = jest.fn().mockImplementation(() => {}) jest.mock('messaging-api-messenger', () => { return { MessengerClient: jest.fn().mockImplementation(() => ({ sendBatch: sendBatchMock })) } }) sendBatchMock.mockReturnValue({ success: true, responseData: [{ code: 200, body: { } }] }) it('send message', async () => { const sendResult = await Send.sendMessage() // 错误:Send并非包含sendMessage的对象,而是函数执行后的Promise expect(sendResult).toEqual('what I want') })
当前问题
sendMessages.js模块加载时就执行了sendMessage(),导出的是函数执行后的Promise,而非函数本身,导致测试时无法重新调用函数,mock无法生效- 测试文件中调用
Send.sendMessage()的方式错误,因为导入的不是函数对象 - 异步方法的mock方式不正确,导致预期返回值未生效
修正方案
1. 修复sendMessages.js的导出逻辑
改为导出函数本身,让测试可以主动调用:
async function sendMessage () { const { MessengerClient } = require('messaging-api-messenger') const client = new MessengerClient({accessToken: 'accessToken'}) return client.sendBatch([{message:'message', to:'someone'}]) } // 导出函数,而非执行结果 module.exports = sendMessage
2. 调整测试文件send.test.js
正确设置mock并验证结果:
// 导入函数本身 const sendMessage = require('./sendMessages') // 针对异步方法,用mockResolvedValue设置预期返回值 const sendBatchMock = jest.fn().mockResolvedValue({ success: true, responseData: [{ code: 200, headers: [], body: {} }] }) // 模拟messaging-api-messenger模块 jest.mock('messaging-api-messenger', () => ({ MessengerClient: jest.fn(() => ({ sendBatch: sendBatchMock })) })) it('send message returns expected result', async () => { // 调用目标函数 const sendResult = await sendMessage() // 验证返回值是否符合预期 expect(sendResult).toEqual({ success: true, responseData: [{ code: 200, headers: [], body: {} }] }) // 额外验证sendBatch的调用情况 expect(sendBatchMock).toHaveBeenCalledTimes(1) expect(sendBatchMock).toHaveBeenCalledWith([{message:'message', to:'someone'}]) })
关键说明
sendBatch是异步方法,必须用mockResolvedValue而非mockReturnValue,才能正确模拟Promise返回值- 原模块的导出错误是核心问题,只有导出函数本身,才能在测试中调用并应用mock逻辑
- 可以添加对
sendBatch调用次数、参数的验证,确保业务逻辑的正确性
内容的提问来源于stack exchange,提问作者jadokao
相关产品推荐
相关产品推荐

