Конструктор класса Mocking Stripe с jest.mock не работает - PullRequest
0 голосов
/ 17 апреля 2020

Я пытаюсь издеваться над конструктором класса Stripe, но, похоже, он не работает должным образом в соответствии с документами Джеста. Я следовал этим инструкциям, чтобы посмеяться над конструктором.

Вот код контроллера, который использует 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 не подвергается насмешке и пытается аутентифицироваться с помощью ключа API StripeAPIKey.

Обновление 1:

Я также попробовал следующее, что привело к тому же результату:

import * as stripe from 'stripe';

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

1 Ответ

0 голосов
/ 17 апреля 2020

Я нашел это сообщение , и я не совсем уверен, почему это сработало вместо использования 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 хочет пролить свет на это. Это было бы здорово!

...