Должен признать, что раньше я не использовал jest-fetch-mock, но из документов и моих маленьких экспериментов похоже, что он заменяет глобальный fetch
надуманной версией. Обратите внимание, что в этом примере не ожидаются какие-либо обещания: https://github.com/jefflau/jest-fetch-mock#simple-mock-and-assert. Это просто проверка того, что fetch
был вызван с правильными аргументами. Поэтому я думаю, что вы можете удалить async / await и утверждать, что есть вызов jsonip.com.
То, что я думаю, чтобы сбить вас с толку, на самом деле - это жизненный цикл React. По сути, это сводится к тому, где вы делаете вызов fetch
. Команда React отговаривает вас ставить «побочные эффекты» (например, fetch
) в constructor
. Вот официальное описание документов React: https://reactjs.org/docs/react-component.html#constructor. К сожалению, я не нашел хорошей документации по , почему . Я полагаю, это потому, что React может вызывать constructor
в нечетные моменты в течение жизненного цикла. Я думаю, что это также причина, по которой вам приходится вручную вызывать функцию fetchData
в вашем тесте.
Лучшая практика для устранения побочных эффектов - componentDidMount
. Вот правильное объяснение того, почему: https://daveceddia.com/where-fetch-data-componentwillmount-vs-componentdidmount/ (хотя стоит отметить, что * * * * componentWillMount
теперь не рекомендуется в Реакте 16.2). componentDidMount
вызывается ровно один раз, только после рендеринга компонента в DOM.
Стоит также отметить, что все это скоро изменится в следующих версиях React. Это сообщение в блоге / видео конференции содержит гораздо больше деталей: https://reactjs.org/blog/2018/03/01/sneak-peek-beyond-react-16.html
Этот подход означает, что он будет отображаться изначально в состоянии загрузки, но как только запрос будет решен, вы можете запустить повторную визуализацию, установив состояние. Поскольку в своем тесте вы используете mount
от Enzyme, при этом будут вызваны все необходимые методы жизненного цикла, включая componentDidMount
, поэтому вы должны увидеть, как вызывается смоделированный fetch
.
Что касается компонента более высокого порядка, я иногда использую уловку, которая, возможно, не лучшая практика, но я думаю, что это довольно полезный хак. Модули ES6 имеют один экспорт default
, а также столько «обычных» экспортов, сколько вам нужно. Я использую это, чтобы экспортировать компонент несколько раз.
Соглашение React заключается в использовании экспорта default
при импорте компонентов (т.е. import MyComponent from './my-component'
). Это означает, что вы можете экспортировать другие файлы из файла.
Мой трюк заключается в export default
компоненте, обернутом HOC, так что вы можете использовать его в своих исходных файлах так же, как и с любым другим компонентом, но также экспортирует развернутый компонент как "обычный" " составная часть. Это будет выглядеть примерно так:
export class MyComponent extends React.Component {
...
}
export default myHOCFunction()(MyComponent)
Затем вы можете импортировать упакованный компонент с помощью:
import MyComponent from './my-component'
И развернутый компонент (т.е. для использования в тестах) с:
import { MyComponent } from './my-component'
Это не самый явный шаблон в мире, но это довольно эргономичный imo. Если вам нужна ясность, вы можете сделать что-то вроде:
export const WrappedMyComponent = myHOCFunction()(MyComponent)
export const UnwrappedMyComponent = MyComponent