При тестировании я продолжал вспоминать шаблон для имитации библиотечных функций, особенно когда мне нужно иметь дело с другим типом импорта, а также с другим компилятором, таким как машинописный текст. Итак, я хотел бы резюмировать основной способ здесь.
Макет библиотеки
Скажем, у вас есть библиотека, экспортирующая пару служебных функций:
export function concat(a, b) {
return a + b
}
export default function sum(a, b) {
return a + b;
}
Чтобы протестировать вышеуказанные функции, мы можем использовать Jest:
import sum, { concat } from '../lib';
describe('lib', () => {
it('sum', () => {
expect(sum(1, 1)).toBe(2);
});
it('concat', () => {
expect(concat('Hello', 'World')).toBe('HelloWorld');
});
});
Это модульное тестирование 101. Довольно часто нам нужно смоделировать некоторые функции, чтобы мы хотели пропустить их реальную реализацию и сразу перейти к смоделированному результату. В этом случае мы просто применяем jest.mock к файлу библиотеки:
import sum, { concat } from '../lib';
jest.mock('../lib');
describe('lib', () => {
it('sum', () => {
sum.mockImplementation(() => 2);
expect(sum()).toBe(2);
});
it('concat', () => {
concat.mockImplementation(() => 'a');
expect(concat()).toBe('a');
});
});
Хорошая вещь в jest.mock заключается в том, что он работает не только для частичного импорта, такого как concat , но также работает для импорта по умолчанию sum прямо из коробки. После этого все функции из библиотеки конвертируются в jest.fn() объект. Поэтому все ваши насмешливые упражнения будут применяться соответственно.
Только когда вы не хотите издеваться над всей библиотекой или хотите установить какое-то значение по умолчанию для одной из функций, вам нужно кодировать jest.mock:
jest.mock('../sum', () => {
return {
__esModule: true,
default: jest.fn(() => 4)
};
});
Вы можете найти больше в разделе документация Jest Mocking Partials, где приводится больше примеров работы с различными ситуациями.
Машинопись
Жизнь не так проста. Когда я перехожу на Typescript, вдруг что-то перестает работать, поэтому люди придумывают всевозможные способы борьбы с этим. На самом деле все, что нам не хватает, это набор типов.
import { concat } from '../lib';
jest.mock('../lib');
describe('lib', () => {
it('concat', () => {
(concat as jest.Mock).mockImplementation(() => 'abc');
expect(concat('a', 'b')).toBe('abc');
});
});
Без приведения concat по-прежнему считается обычной функцией в Typescript. Поэтому нам нужно привести его к jest.Mock. Из этого Stackoverflow правильным способом может быть преобразование его в MockedFunction:
import { concat } from '../lib';
jest.mock('../lib');
const mockedConcat = concat as jest.MockedFunction<typeof concat>;
describe('lib', () => {
it('concat', () => {
mockedConcat.mockImplementation(() => 'abc');
expect(concat('a', 'b')).toBe('abc');
});
});
В той же ветке кто-то упомянул еще один хороший простой способ победить его через spyOn :
import * as _ from '../lib';
jest.mock('../lib');
const concat = jest.spyOn(_, 'concat');
describe('lib', () => {
it('concat', () => {
concat.mockImplementation(() => 'abc');
expect(_.concat('a', 'b')).toBe('abc');
});
});
Единственная загвоздка в том, что вам нужно иметь доступ ко всей библиотеке, такой как * as _ , потому что шпион может быть применен только к родительскому object.
Краткое содержание
Я надеюсь, что у меня будет лучшая жизнь в фиктивных модулях с вышеуказанными знаниями. В основном делайте jest.mock и, если тип отсутствует, приведите его, прежде чем продолжить по-старому. Вот и все.
Дополнительные материалы на PlainEnglish.io.
Подпишитесь на нашу бесплатную еженедельную рассылку новостей. Подпишитесь на нас в Twitter, LinkedIn, YouTube и Discord .
Заинтересованы в масштабировании запуска вашего программного обеспечения? Ознакомьтесь с разделом Схема.