Sinon заглушки требуют несколько раз - PullRequest
0 голосов
/ 13 мая 2019

Итак, я работаю над тестами для Google Cloud Functions и испытываю трудности с заглушкой библиотек node_modules с различным поведением.

В начале тестового файла у меня есть заглушка для firebase-admin библиотека в boforeAll.

Затем мне нужно выполнить различные тесты it should export idinInitRequest и idin issue с соответствующими требованиями к тестируемому файлу '../src/index', который является функцией облака.

Первый работает как положено.Глупо с моим callsFake правильно.

Проблема возникает при втором тесте.Во втором тесте я издеваюсь над другой библиотекой, которая используется в облачной функции node-idin-beta.В этом тесте библиотека firebase-admin не заглушается.На самом деле, он ведет себя так, как будто его не заглушали, используя все методы по умолчанию.A console.log(admin) внутри функции показывает это:

console.log src/app.ts:122
  { firestore: [Function: firestore], auth: [Function: auth] }
console.log src/app.ts:122
  FirebaseApp {
    firebaseInternals_:
      FirebaseNamespaceInternals {
        firebase_:
          FirebaseNamespace {
              __esModule: true,
              credential: [Object],
              SDK_VERSION: '6.3.0',
              Promise: [Function: Promise],
              INTERNAL: [Circular],
            (...)

Из журнала видно, что при первом выполнении он работает правильно, но не во втором.

Обоснование необходимостиФункция в каждом тесте обусловлена ​​разным поведением, которое библиотеки могут выполнять в разных тестах.

Я не знаю, как заглушить firebase-admin еще раз после первого запроса.

ЗдесьЯ оставляю кусок кода:

import { ContextOptions } from 'firebase-functions-test/lib/main';
import setup from './lib/setup.lib';

const { admin, sinon, assert, testEnv } = setup;

describe('Cloud Functions', (): void => {
  let myFunctions;
  let adminInitStub;

  beforeAll((): void => {
    // [START stubAdminInit]
    // If index.js calls admin.initializeApp at the top of the file,
    // we need to stub it out before requiring index.js. This is because the
    // functions will be executed as a part of the require process.
    // Here we stub admin.initializeApp to be a dummy function that doesn't do anything.
    adminInitStub = sinon.stub(admin, 'initializeApp');
    process.env.FUNCTION_NAME = 'idinInitRequest';
    // [END stubAdminInit]
  });

  afterAll((): void => {
    // Restore admin.initializeApp() to its original method.
    adminInitStub.restore();
    // Do other cleanup tasks.
    process.env.FUNCTION_NAME = '';
    myFunctions = undefined;
    testEnv.cleanup();
  });

  afterEach((): void => {
    myFunctions = undefined;
    // Restore mocks
    jest.resetModules();
  });

  describe('idinInitRequest', (): void => {
    it('it should export idinInitRequest', (): void => {
      adminInitStub = adminInitStub.callsFake((): any => ({
        firestore: (): any => ({
          settings: (): void => {},
        }),
        auth: (): void => { },
      }));
      myFunctions = require('../src/index');

      const cFunction = require('../src/idinInitRequest');
      assert.isObject(myFunctions);
      assert.include(myFunctions, { idinInitRequest: cFunction });
    });

    it('idin issue', async (): Promise<void> => {
      jest.mock('node-idin-beta', (): { [key: string]: any } => ({
        getTransactionResponse: (): Promise<any> => Promise.reject('shiat'),
      }));

      adminInitStub = adminInitStub.callsFake((): any => ({
        firestore: (): any => ({
          settings: (): void => {},
        }),
        auth: (): void => { },
      }));

      myFunctions = require('../src/index');

      const wrapped = testEnv.wrap(myFunctions.idinInitRequest);
      const onCallObjects: [any, ContextOptions] = [
        { issuerId: 'issuer', merchantReturnUrl: 'url' },
        { auth: { uid: '32344' } },
      ];

      await expect(wrapped(...onCallObjects)).rejects.toThrow('There was an error connecting to the idin issuer');
    });
  });
});

1 Ответ

0 голосов
/ 13 мая 2019

Следуя объяснению разницы между заглушкой и макетом здесь , я решил также смоделировать firebase-admin, потому что да, это предопределенное поведение, но оно будет меняться в зависимости от теста. И это работает. Вот это код:

describe('Cloud Functions', (): void => {
  let myFunctions;

  beforeAll((): void => {
    process.env.FUNCTION_NAME = 'idinInitRequest';
  });

  afterAll((): void => {
    process.env.FUNCTION_NAME = '';
    myFunctions = undefined;
    testEnv.cleanup();
  });

  afterEach((): void => {
    myFunctions = undefined;
    // Restore mocks
    jest.resetModules();
  });

  describe('idinInitRequest', (): void => {
    it('it should export idinInitRequest', (): void => {
      jest.mock('firebase-admin', (): { [key: string]: any } => ({
        initializeApp: () => ({
          firestore: (): any => ({
            settings: (): void => {},
          }),
          auth: (): void => { },
        })
      }));
      myFunctions = require('../src/index');

      const cFunction = require('../src/idinInitRequest');
      assert.isObject(myFunctions);
      assert.include(myFunctions, { idinInitRequest: cFunction });
    });

    it('idin issue', async (): Promise<void> => {
      jest.mock('node-idin-beta', (): { [key: string]: any } => ({
        getTransactionResponse: (): Promise<any> => Promise.reject('shiat'),
      }));

      jest.mock('firebase-admin', (): { [key: string]: any } => ({
        initializeApp: () => ({
          firestore: (): any => ({
            settings: (): void => {},
          }),
          auth: (): void => { },
        })
      }));

      myFunctions = require('../src/index');

      const wrapped = testEnv.wrap(myFunctions.idinInitRequest);
      const onCallObjects: [any, ContextOptions] = [
        { issuerId: 'issuer', merchantReturnUrl: 'url' },
        { auth: { uid: '32344' } },
      ];

      await expect(wrapped(...onCallObjects)).rejects.toThrow('There was an error connecting to the idin issuer');
    });
  });
});

Если у вас есть другой подход для решения этой проблемы, не стесняйтесь поделиться им.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...