tl; dr: Если вы пишете модульные тесты с помощью Typescript и хотите имитировать поддельные события React, посмотрите здесь для типов React и здесь для типов DOM. Создавая фальшивое событие, работайте в обратном направлении, добавляя типы, при необходимости используйте оператор as, чтобы не добавлять каждое свойство каждого типа.

Допустим, вы похожи на меня и только что начали работать над проектом с использованием новейших технологий в мире Javascript: Typescript, React, Jest и Enzyme. Вы пишете компонент, содержащий некоторый HTML-код, основанный на событиях. В этом примере я собираюсь использовать тег ввода HTML для загрузки файла.

Вот образец родительского компонента с обработчиком кликов:

Вот дочерний компонент с фактическим элементом ввода HTML:

Обратите внимание, что обработчик onChange принимает событие типа ChangeEvent. Теперь предположим, что я хочу написать несколько модульных тестов, имитирующих это событие. Вот как бы вы это сделали:

Чтобы создать фальшивый объект события в строке 23, вероятно, лучше всего работать в обратном направлении. Вам нужно будет найти типы здесь. Найдите нужный пакет, но в этом случае мы найдем ответ. Поскольку мы создаем ChangeEvent, обратите внимание на тип. Этот ChangeEvent расширяет SyntheticEvent.

Вы можете спросить себя: «Что происходит с преобразованием события в ChangeEvent?» Обычно с машинописным текстом вы применяете тип к переменной, выполняя что-то вроде:

событие const: React.ChangeEvent ‹HTMLInputElement› = {…}

Однако TypeScript это не нравится. Он попросит вас в основном добавить каждое из полей, перечисленных в SyntheticEvent (т.е. пузырьки, отменяемые, defaultPrevented и т. Д.). Мы приводим его, используя as, о котором вы можете прочитать здесь, и это позволяет вам обойти весь этот лишний мусор, который вы ранее хотели добавить.

Далее идет список файлов в строке 17. Я обнаружил, что это результат event.currentTarget.files, просто записав все в консоль браузера (поверьте мне). FileList - это не тип реакции, а тип HTML DOM, который можно увидеть здесь. Я не знаю, почему это так, но в основном FileList ожидает длину, функцию под названием элемент и пару ключ-значение из 0 - ›file.

(Почему существует эта странная функция под названием «элемент», которая даже не содержит файла? Я не знаю, может быть, вы лучше меня понимаете природу javascript, чем я.)

Мы используем здесь обычный машинописный код const fileList: FileList вместо оператора «as», потому что все поля легко подделать.

Двигаемся дальше.

Наконец, чтобы смоделировать файловую переменную в строке 12, посмотрите определение типа здесь. Мы приводим его с использованием as, поэтому нам не нужно добавлять некоторые другие поля blob.

Вот и все! Мы успешно смоделировали событие React в модульном тесте Jest.