【问题标题】:Mock Stripe API with jest in Node typescript在 Node typescript 中使用 jest 模拟 Stripe API
【发布时间】:2021-09-11 17:28:06
【问题描述】:

我一直在尝试模拟 Stripe API 以执行测试。我对用 jest 模拟函数的经验很少,但我已经深入研究了如何模拟 Stripe 的 API,但似乎没有工作。

我的文件结构如下:

src/payment-gateways/stripe.ts

import Stripe from 'stripe'
import { PAYMENT_STRIPE_API_SECRET_KEY } from '../config'

const stripe = new Stripe(PAYMENT_STRIPE_API_SECRET_KEY, {
  apiVersion: '2020-08-27',
})

export default stripe

然后在我的stripe.test.ts 上调用我的 API 端点,以便在逻辑中间创建一个条带客户。

我已经尝试过的是:

src/tests/__mocks__/stripe.ts

export class Stripe {}
const stripe = jest.fn(() => new Stripe())


export default stripe

src/...../stripe.test.ts

import { Stripe } from 'stripe'

Stripe.prototype.customers = {
    create: jest.fn(() => ({
              id: 1,
           })),
  } as unknown as Stripe.CustomersResource

//And also tried this without __mocks__

jest.mock('../../../../../../payment-gateways/stripe', () => {
  return jest.fn(() => ({
    customers: {
      create: jest.fn(() =>
        Promise.resolve({
          id: '1',
        })
      ),
    },
  }))
})

describe('stripe workflow', ()=> {
   it('creates a customer', async () => {
      await apollo.mutate...
   .
   .
   .
 })
})

但我不断收到错误[[GraphQLError: Cannot read property 'create' of undefined]] 两种方法。

我想我在 jest 使用模拟的过程中遗漏了一些东西

【问题讨论】:

  • 你解决了吗?遇到同样的问题:(
  • 还没有,因为我正在做一个不同的项目,所以没有再看这个。但如果我能解决这个问题,我会标记你

标签: node.js typescript testing jestjs stripe-payments


【解决方案1】:

您可以通过模拟 Stripe 的实现来完成此操作:

const mockedCustomerCreate = jest.fn();

jest.mock('stripe', () => {
  const customers = jest.fn();
  // @ts-ignore
  customers.create = (...args) = mockedCustomerCreate(...args);

  return jest.fn().mockImplementation(() => ({
    customers
  }));
});

describe('foo', () => {
  test('bar', async () => {
    mockedCustomerCreate.mockResolvedValue({});
    
    // your test stuff

    expect(mockedCustomerCreate).toBeCalledTimes(1);
  });
})

关于此方法的几点注意事项:

  • // @ts-ignore 是强制输入所必需的
  • customers.create 需要包装在另一个函数中,否则开玩笑会抱怨
  • 您需要对您在 Stripe 对象上使用的每个函数执行类似的操作

【讨论】:

  • @vwos 看看。谢谢,当我再次结束这个问题时,我会试一试。我会留下一些反馈
【解决方案2】:

在节点中模拟 Stripe API 真的很痛苦,所以我希望这个评论对某人有用。我改进了@MrDiggles 的回答。我在嘲笑paymentIntent.create 方法,但理论是一样的。真的,我刚刚使嵌套的模拟函数隐式返回并删除了一些不必要的行,以及满意的 TS 编译器。这里的关键部分是create: (...args: any) => mockPaymentsIntentsCreate(...args) as unknown,,它允许在jest.mock 范围之外访问模拟(因此可以针对不同的测试更改行为,如图所示),但仍被提升,因此在stripe 之前运行在被测代码中导入。我实际上不是 100% 确定这是如何工作的。改用create: mockPaymentsIntentsCreate 会给你一个ReferenceError: Cannot access 'mockPaymentsIntentsCreate' before initialization。希望比我聪明的人能回答这个问题!

index.ts

import Stripe from 'stripe';

const stripe = new Stripe('sk_test_...', {
    apiVersion: '2020-08-27',
});

export const createPaymentIntent = async (parameters: Stripe.PaymentIntentCreateParams) => stripe.paymentIntents.create(parameters);

index.spec.ts

import { createPaymentIntent } from '../../src/stripe-client';

const mockPaymentsIntentsCreate = jest.fn();

jest.mock('stripe', () => jest.fn(() => ({
    paymentIntents: {
        create: (...args: any) => mockPaymentsIntentsCreate(...args) as unknown,
    },
})));

describe('stripe-client', () => {
    test('create payment intent happy path', async () => {
        const paymentIntentsCreateResponse = { id: '123' };
        mockPaymentsIntentsCreate.mockResolvedValueOnce(paymentIntentsCreateResponse);

        const result = await createPaymentIntent({
            amount: 100,
            currency: 'gbp',
        });

        expect(result).toBe(paymentIntentsCreateResponse);
    });

    test('create payment intent unhappy path', async () => {
        const paymentIntentsCreateResponse = 'oops';
        mockPaymentsIntentsCreate.mockRejectedValueOnce(paymentIntentsCreateResponse);

        await expect(createPaymentIntent({
            amount: 100,
            currency: 'gbp',
        })).rejects.toBe(paymentIntentsCreateResponse);
    });
});

【讨论】:

    猜你喜欢
    • 2018-07-23
    • 2020-03-18
    • 2021-01-13
    • 1970-01-01
    • 2019-09-26
    • 2021-01-03
    • 2018-12-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多