React Hook Testing Детские обратные вызовы - PullRequest
1 голос
/ 13 июня 2019

Таким образом, тест должен обеспечить ввод для функции и проверить вывод. С React вход для функции может исходить либо от props, либо от дочернего компонента / функции. Хорошо, есть и другие способы, но сейчас давайте посмотрим на эти два пути.

У меня есть компонент Container, который выполняет некоторую бизнес-логику и отображает дочерний элемент:

import React, { useEffect } from 'react'
import ExampleView from './ExampleView'

const ExampleContainer = ({ onSomeBusinessDone, iHaveMounted }) => {
  useEffect(() => {
    // An example of a "on mount" style effect that we may need to test
    // Grab data, do some initial logic whatever, but test that I call a prop
    // within this mount call
    iHaveMounted()
  }, [])

  const onDoSomeBussinessLogic = (eventData = {}) => {
    // Do something with the data perhaps
    eventData.whoa = true
    onSomeBusinessDone(eventData)
  }

  return <ExampleView onSomething={onDoSomeBussinessLogic} />
}

export default ExampleContainer

Этот контейнер обеспечивает стиль обратного вызова prop для дочернего элемента. Цель состоит в том, чтобы проверить, что, когда дочерний элемент вызывает эту функцию, Контейнер что-то с ней делает, а затем вызывает свой собственный стиль обратного вызова (или выход, который мы хотели бы проверить).

Проблема, с которой я сталкиваюсь, состоит в том, как вызвать эту функцию, которая предоставляется ребенку в Jest / React с помощью хуков?

Настройки немного сложно объяснить словами, но у меня есть репозиторий и коды: https://github.com/Kikketer/hooks-test-questions https://codesandbox.io/embed/hooks-tests-questions-vvrv6

Песочницу лучше всего смотреть, но я не мог понять, как запустить там шутку, поэтому было бы проще всего попробовать ее после клонирования.

Здесь есть пара вещей:

  1. Я не могу использовать неглубокое средство визуализации, поскольку мне также нужно проверить, что useEffect перехватчики также вызывают свойство.
  2. Я использую макет рендеринга дочернего компонента в функции Container, чтобы он не пытался рендерить дочерний компонент, так как я только тестирую контейнер, и мне не нужно беспокоиться о зависимостях или других ошибках этого дочернего элемента. Только что я передаю полезные и ожидаемые реквизиты.

Мой тест выглядит так:

  jest.mock('./ExampleView', () => props => <div data-id="ExampleView" {...props} />)
  ...
  ...

  test('when a child does something expect the prop function to have `whoa`', () => {
    const onSomething = jest.fn()
    act(() => {
      renderer.create(<ExampleContainer onSomething={onSomething} />)
    })
    // Somehow trigger the child's action... not sure how
    // Urm....
    expect(onSomething).toHaveBeenCalledWith({ clicked: true, whoa: true })
  })

Опять я высмеиваю вид, потому что я не могу использовать неглубокое средство визуализации и не хочу отображать детей. Я просто хочу проверить реквизит (что делает снимок красиво).

Как я это сделал, используя класс

До хуков я мог бы добраться до компонента и напрямую вызвать функцию:

const onSomeBusinessDone = jest.fn()
const iHaveMounted = jest.fn()
const component = new ExampleContainer({onSomeBusinessDone, iHaveMounted})
component.onDoSomeBussinessLogic({clicked: true})
// I can check to see that given the input (clicked) I get the output:
expect(onSomeBusinessDone).toHaveBeenCalledWith({clicked: true, whoa: true})

Я понимаю, что создание реактивного компонента new не одобряется, но это позволило бы мне довольно просто выполнить этот тест. Я не верю, что смогу сделать подобный формат с Hooks, потому что это функция, которая не раскрывает внутренние функции.

...