Внешний модуль макета узла по умолчанию с использованием метода с использованием jest - PullRequest
2 голосов
/ 31 марта 2019

В нашем CLI узла у нас есть простой метод:

'use strict';

const ora = require('ora');

module.exports = function startSpinner({ textOnStart, color, spinnerType }) {
  const spinner = ora({
    text: textOnStart,
    color: color || 'cyan',
    spinner: spinnerType || ''
  }).start();
};

Мы пытаемся использовать jest для проверки этого метода.Нам нужно выполнить два теста:

  • Проверка того, что ora была вызвана с правильным аргументом объекта
  • Проверка того, что метод start() был вызван позднее

Это, как говорится, мы не можем добиться, чтобы правильно смоделировать ora модуль.

ora является третьей стороной, которая в основном построена следующим образом:

class Ora {
    constructor(options){}
    start(){ }
}

const oraFactory = function (opts) {
    return new Ora(opts);
};

module.exports = oraFactory;
module.exports.default = oraFactory;

Мы ищем способ

Мы пытались использовать автоматическое моделирование:

const ora = require('ora');

jest.mock('ora');

const startSpinner = require('./startSpinner');

describe('startSpinner', () => {
  beforeEach(() => {
    startSpinner({});
  });

  describe('ora', () => {
    it('should call ora', () => {
      expect(ora).toHaveBeenCalled();
    });

    it('should call ora start', () => {
      expect(ora.start).toHaveBeenCalled();
    });
  });
});

Но оба теста терпят неудачу соответственно:

Ошибка сопоставления: полученное значение должно бытьфиктивная или шпионская функция

Received has type:  function
Received has value: [Function oraFactory]

и

Ошибка сопоставления: полученное значение должно быть фиктивной или шпионской функцией

Received has value: undefined

Мы попытались использовать пользовательский макет:

const ora = require('ora');

jest.mock('ora', () => {
  return jest.fn().mockImplementation(() => {
    return { start: jest.fn() };
  });
});

, и он получился с таким же точным результатом.

Мы даже пытались преобразовать наш тест в машинописный текст и затем использовать:

import * as ora from 'ora';

const startMock = jest.fn();
jest.mock('ora', () => {
  return jest.fn().mockImplementation(() => {
    return { start: startMock };
  });
});

Тогда мы смогли успешно проверить, что ora был вызван.Но мы закончили с ошибкой для expect(ora.start).toHaveBeenCalled(); или даже expect((ora as any).start).toHaveBeenCalled();:

Ошибка TS2339: Свойство 'start' не существует для типа 'typeof import (' / Users / Dev / cli /node_modules / ora / index ") '.

Наверняка вызвано тем, что определение типа импортируемого ora равно export default function ora(options?: Options | string): Ora;

Как затем издеваться над третьей стороной, такой как oraв тестовой среде узла jest?

1 Ответ

1 голос
/ 31 марта 2019

У вас есть несколько вариантов:


Вы можете смоделировать ora следующим образом:

jest.mock('ora', () => {
  const start = jest.fn();
  const result = { start };
  return jest.fn(() => result);
});

... и затем позвонить ora, чтобы получитьобъект, который он возвращает (поскольку он всегда возвращает один и тот же объект) и использует этот объект для доступа к start:

it('should call ora start', () => {
  const result = ora();
  expect(result.start).toHaveBeenCalled();  // Success!
});

Или, если хотите, вы можете присоединить макет start в качестве свойствана ora макет как простой способ получить к нему доступ во время ваших тестов, например:

const ora = require('ora');

jest.mock('ora', () => {
  const start = jest.fn();
  const result = { start };
  const ora = jest.fn(() => result);
  ora.start = start;  // attach the start mock to ora
  return ora;
});

const startSpinner = require('./startSpinner');

describe('startSpinner', () => {
  beforeEach(() => {
    startSpinner({});
  });

  describe('ora', () => {
    it('should call ora', () => {
      expect(ora).toHaveBeenCalled();  // Success!
    });

    it('should call ora start', () => {
      expect(ora.start).toHaveBeenCalled();  // Success!
    });
  });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...