В нашем 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?