Lambda函数Mock Stripe SDK报错:TypeError: stripe_1.default is not a constructor
解决Lambda中Mock Stripe SDK的构造函数报错问题
问题背景
我在Lambda函数中尝试Mock Stripe SDK,相关代码及报错如下:
Config文件中创建Stripe实例的代码
export const stripe = new Stripe(STRIPE_SECRET_KEY, { apiVersion: '2020-08-27', typescript: true, maxNetworkRetries: 2, });
Lambda函数中使用实例的方式
import { stripe, STRIPE_TEST_USERS } from '../config'; await stripe.invoices.retrieve(id)
报错信息
TypeError: stripe_1.default is not a constructor 36 | }); 37 | > 38 | export const stripe = new Stripe(STRIPE_SECRET_KEY, { | ^ 39 | apiVersion: '2020-08-27', 40 | typescript: true, 41 | maxNetworkRetries: 2,
已尝试的三种无效Mock方法
jest.mock("stripe", () => { return jest.fn().mockImplementation(()=> { return { invoices: { retrieve: () =>jest.fn(), }, }; }); });
jest.mock('stripe', () => jest.fn().mockImplementation(() => ({ invoices: { retrieve: () => jest.fn() }, })) );
jest.mock('stripe', () => ({ ...jest.mock('stripe'), Stripe: jest.fn().mockImplementation(() => { return { invoices: jest.fn().mockImplementation(() => { return { retrieve: jest.fn(), }; }), }; }), }));
解决方案
报错核心原因是:Stripe SDK采用默认导出构造函数,但之前的Mock没有正确模拟这个默认导出结构。以下是两种可行的Mock方案:
方案一:基础版Mock
直接将模拟的构造函数作为模块的默认导出返回:
jest.mock('stripe', () => { // 模拟Stripe构造函数,返回包含invoices方法的对象 const mockStripe = jest.fn(() => ({ invoices: { retrieve: jest.fn().mockResolvedValue({ // 这里可以自定义模拟的返回值,比如发票ID、金额等 id: 'mock-test-invoice', amount_due: 5000 }) } })); // 关键:将模拟函数作为default导出,匹配Stripe的实际导出结构 return { default: mockStripe }; });
方案二:进阶版Mock(支持更多场景)
如果需要模拟Stripe的其他静态属性或方法,可以扩展Mock结构:
jest.mock('stripe', () => { // 单独模拟retrieve方法,方便后续验证调用 const mockRetrieveInvoice = jest.fn().mockResolvedValue({ id: 'mock-invoice-123', status: 'paid' }); return { default: jest.fn(() => ({ invoices: { retrieve: mockRetrieveInvoice } })), // 若代码用到Stripe的命名导出(比如枚举),可在此添加模拟 Stripe: { Invoice: { Status: { PAID: 'paid' } } } }; });
验证Mock有效性
在测试用例中可以验证Mock的调用情况:
import { stripe } from '../config'; import { yourLambdaHandler } from '../lambda'; test('调用Lambda时正确触发Stripe发票查询', async () => { const testInvoiceId = 'test-123'; // 执行Lambda处理函数 await yourLambdaHandler({ /* 传入测试事件参数 */ }); // 验证Stripe构造函数被实例化 expect(require('stripe').default).toHaveBeenCalled(); // 验证retrieve方法被传入正确ID调用 expect(stripe.invoices.retrieve).toHaveBeenCalledWith(testInvoiceId); });
之前方法无效的原因
- 前两种方法直接返回模拟函数,但未将其设置为模块的
default导出,导致new Stripe()时找不到构造函数(stripe_1.default为undefined)。 - 第三种方法试图模拟命名导出
Stripe,但实际代码中是导入默认导出的构造函数,结构不匹配,因此无效。
内容的提问来源于stack exchange,提问作者gabut faedah
相关产品推荐
相关产品推荐

