Jest: Как протестировать функцию, которая вызывает bind(this)

У меня есть родительский компонент, который выглядит так:

export class Header extends Component {
  constructor(props) {
    super(props)
    this.state = { activeTab: TAB_NAMES.NEEDS_REVIEW }
  }

  filterByNeedsReview() {
    const { filterByNeedsReviewFn } = this.props
    this.setState({ activeTab: TAB_NAMES.NEEDS_REVIEW })
    filterByNeedsReviewFn()
  }


  render() {
    return (
        ...
          <FilterTab
            ...
            onClick={this.filterByNeedsReview.bind(this)}
          />
          ...
    )
  }
}

Я пытаюсь проверить, что ребенок был загружен правильным реквизитом. Первоначально у меня была анонимная функция: onClick={ () => this.filterByNeedsReview() }, но я не мог ее проверить, поэтому вместо этого я попытался перейти к bind(this).

Однако у меня возникают проблемы с имитацией функции bind:

  it('renders a filter tab with the right props for needs review', () => {
    const bounded = jest.fn()
    const boundedFilterByNeedsReview = jest.fn(() => {
      return { bind: bounded }
    })
    Header.prototype.filterByNeedsReview = boundedFilterByNeedsReview
    expect(
      shallowRender()
        .find(FilterTab)
        .findWhere(node =>
          _.isMatch(node.props(), {
            ... // other props
            onClick: bounded, //<-------------- FAILS WHEN I ADD THIS LINE
          })
        )
    ).toHaveLength(1)
  })

person bigpotato    schedule 24.10.2018    source источник


Ответы (1)


Привяжите метод в конструкторе, чтобы предотвратить повторную привязку метода при каждом рендеринге компонента:

constructor(props) {
    super(props)
    this.state = { activeTab: TAB_NAMES.NEEDS_REVIEW }
    this.filterByNeedsReview = this.filterByNeedsReview.bind(this)
}

Затем передайте связанный метод в качестве реквизита дочернему элементу:

<FilterTab
    ...
    onClick={this.filterByNeedsReview}
/>

Здесь вам не нужно использовать анонимную функцию.

person SeanMcP    schedule 31.10.2018
comment
Хороший. Значит, в этом случае Header.prototype.filterByNeedsReview = boundedFilterByNeedsReview не сработает? Вместо этого мне придется заглушить экземпляр wrapper.instance().filterByNeedsReview = jest.fn()? - person bigpotato; 01.11.2018
comment
@Edmund Вы можете получить доступ к методу, как вы упомянули, но вам не нужно будет переназначать его с помощью jest.fn(). Вызовите функцию как есть, затем убедитесь, что состояние было обновлено и что this.props.filterByNeedsReviewFn было вызвано. - person SeanMcP; 05.11.2018