【问题标题】:Mocking Stripe class constructor with jest.mock not working使用 jest.mock 模拟 Stripe 类构造函数不起作用
【发布时间】:2020-05-19 09:04:10
【问题描述】:

我正在尝试模拟 Stripe 的类构造函数,但根据 Jest 的文档,它似乎没有正常工作。我按照these 的说明来模拟构造函数。

这是使用 Stripe 的控制器代码 (/src/controllers/stripe.ts):

import Stripe from 'stripe';

/**
 * Creates a Stripe Customer
 *
 * @param {object} req The express request object.
 * @param {object} res The express response object.
 * @param {function} next The express next function.
 */
export const createStripeCustomer = async (
  req: Request,
  res: Response,
  next: NextFunction
): Promise<Response | void> => {
  const stripeApiKey: string = process.env.STRIPE_API_KEY ? process.env.STRIPE_API_KEY : '';
  const user: IUser = req.user as IUser;

  /** Send error if no Stripe API key or no user */
  if (!stripeApiKey) {
    return next(
      'Something went wrong. If this problem persists, please contact technical support.'
    );
  } else if (!user) {
    res.status(401);
    return next('Unauthroized Access');
  }

  const stripe = new Stripe(stripeApiKey, {
    apiVersion: '2020-03-02',
  });
};

这里是测试代码(/src/tests/controllers/stripe.ts):

  import Stripe from 'stripe';

  /**
   * Return error if stripe.customer.create fails
   */
  test('Should error if stripe.customer.create fails', async (done) => {
    process.env.STRIPE_API_KEY = 'StripeAPIKey';

    jest.mock('stripe', () => {
      return jest.fn().mockImplementation(function () {
        return {
          customers: {
            create: jest.fn().mockRejectedValue('Stripe error'),
          },
        };
      });
    });

    mockRequest = ({
      body: {
        payment_method: mockPaymentMethodObject,
      },
      user: {
        email: 'jdoe@google.com',
        first_name: 'John',
        last_name: 'Doe',
      },
    } as unknown) as Request;

    await createStripeCustomer(mockRequest, mockResponse, mockNextFunction);

    expect(mockNextFunction).toHaveBeenCalledTimes(1);
    expect(mockNextFunction).toHaveBeenCalledWith('Stripe error');
    done();
  });

我的期望是测试应该通过,但我收到以下错误:

expect(jest.fn()).toHaveBeenCalledWith(...expected)

    Expected: "Stripe error"
    Received: [Error: Invalid API Key provided: StripeAPIKey]

    Number of calls: 1

      137 | 
      138 |     expect(mockNextFunction).toHaveBeenCalledTimes(1);
    > 139 |     expect(mockNextFunction).toHaveBeenCalledWith('Stripe error');
          |                              ^
      140 |     done();
      141 |   });
      142 |   test('Should error if user update fails', () => {});

      at _callee3$ (src/tests/controllers/stripe.test.ts:139:30)
      at tryCatch (node_modules/regenerator-runtime/runtime.js:45:40)
      at Generator.invoke [as _invoke] (node_modules/regenerator-runtime/runtime.js:274:22)
      at Generator.prototype.<computed> [as next] (node_modules/regenerator-runtime/runtime.js:97:21)
      at asyncGeneratorStep (node_modules/@babel/runtime/helpers/asyncToGenerator.js:3:24)
      at _next (node_modules/@babel/runtime/helpers/asyncToGenerator.js:25:9)

这似乎是在抛出,因为 Stripe 没有被模拟,它正在尝试使用 StripeAPIKey 的 API 密钥进行身份验证。

更新 1:

我也尝试了以下方法,结果相同:

import * as stripe from 'stripe';

jest.mock('stripe', () => {
      return {
        Stripe: jest.fn().mockImplementation(() => ({
          customers: {
            create: jest.fn().mockRejectedValueOnce('Stripe error'),
          },
        })),
      };
    });

【问题讨论】:

  • 尝试将jest.mock('stripe', () =&gt; {改为jest.mock('Stripe', () =&gt; {,构造函数以大写开头S
  • 我试过了,得到了同样的结果。我最初使用 stripe 是因为 jest.mock() 模拟了模块本身。

标签: node.js jestjs stripe-payments


【解决方案1】:

我发现了这个post,但我不确定为什么它会起作用而不是使用jest.mock(),但这是我让测试开始通过的方法。我在/tests/__mocks__/ 中创建了一个单独的文件。

/tests/mocks/stripe.js(注意:这不是TS文件)

export default class Stripe {}

这是我在 /tests/src/controllers/stripe.ts 中的新测试

  /**
   * Return error if stripe.customer.create fails
   */
  test('Should error if stripe.customer.create fails', async (done) => {
    Stripe.prototype.customers = ({
      create: jest.fn().mockRejectedValueOnce('Stripe error'),
    } as unknown) as Stripe.CustomersResource;

    await createStripeCustomer(mockRequest, mockResponse, mockNextFunction);

    expect(Stripe.prototype.customers.create).toHaveBeenCalledTimes(1);
    expect(mockNextFunction).toHaveBeenCalledTimes(1);
    expect(mockNextFunction).toHaveBeenCalledWith('Stripe error');
    done();
  });

如果有更多 Jest/Typescript 知识的人想要对此有所了解。那太好了!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-27
    • 1970-01-01
    • 1970-01-01
    • 2012-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多