使用Jest Mock AWS SNS时遇TypeError: sns.publish is not a function求助
解决Mock AWS.SNS时出现的
TypeError: sns.publish is not a function问题 我来帮你排查这个问题,你的错误主要来自两个地方:错误的mock重置方式和提前获取mock引用的时机问题,下面一步步给你解决:
错误原因分析
jest.restoreAllMocks()的误用:你在beforeEach里调用了这个方法,它会把你通过jest.mock创建的SNS构造函数mock恢复成AWS的原始实现。这就导致测试运行时,new SNS()生成的是真实的SNS客户端实例(而非你定义的mock对象),而真实实例在无配置的测试环境中无法正确初始化,最终抛出sns.publish is not a function。- 提前获取mock引用的问题:你在模块顶部就创建了
snsPublishPromise,但beforeEach里的mock重置会让这个引用失效,后续的mock配置根本不会作用到测试中实际使用的SNS实例上。
修正后的测试用例代码
// 保持jest.mock在最顶部,确保模块导入前就完成mock jest.mock('aws-sdk', () => { const mockedPublish = jest.fn().mockReturnThis(); const mockedPromise = jest.fn(); const mockedSNS = { publish: mockedPublish, promise: mockedPromise }; return { SNS: jest.fn(() => mockedSNS), }; }); import aws, { SNS } from 'aws-sdk'; import { thishandler } from "../src/index"; // 提前获取mock的SNS构造函数和实例的快捷方法 const mockSNSConstructor = aws.SNS as jest.Mock; const getMockSNSInstance = () => mockSNSConstructor.mock.results[0].value; describe("async testing", () => { beforeEach(() => { // 只清除mock的调用记录,不要恢复原始实现 jest.clearAllMocks(); // 重置环境变量,保证每次测试的干净状态 process.env.ENRICHER_SNS_TOPIC_ARN = "OUR-SNS-TOPIC"; }); it("async test", async () => { const mockedResponseData ={ "Success": "OK" }; // 获取mock的SNS实例,配置promise的返回值 getMockSNSInstance().promise.mockResolvedValueOnce(mockedResponseData); // 执行测试 await thishandler(thisSNSEvent); // 可选:添加断言验证publish是否被正确调用 expect(getMockSNSInstance().publish).toHaveBeenCalledWith({ Message: JSON.stringify(/* 这里填入你预期的snsMessagetoBeSent内容 */), TopicArn: "OUR-SNS-TOPIC" }); expect(getMockSNSInstance().promise).toHaveBeenCalled(); }); });
关键调整点说明
- 替换mock重置方法:移除
jest.restoreAllMocks()和jest.resetAllMocks(),改用jest.clearAllMocks()——它只会清除mock的调用次数、参数等记录,不会破坏我们自定义的mock实现。 - 正确获取mock实例:通过
mockSNSConstructor.mock.results[0].value获取测试中实际使用的SNS mock实例,确保mock配置能准确作用到目标对象上。 - 环境变量统一管理:把环境变量配置移到
beforeEach中,保证每次测试都能从干净的状态开始。
这样调整后,你的mock就能正常工作,不会再出现sns.publish is not a function的错误了。
内容的提问来源于stack exchange,提问作者fly.bird
相关产品推荐
相关产品推荐

