Как получить доступ к состоянию на вложенном компоненте React, завернутом HOC?

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

Предположим, что этот компонент <Foo/> использует компонент <Link> из ReactRouter, и поэтому нам нужно обернуть его в <MemoryRouter> для тестирования.

В этом и заключается проблема.

it('puts the lotion in the basket', () => {
  const wrapper = mount(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  wrapper.state('name') // this returns null! We are accessing the MemoryRouter state, which isn't what we want!
  wrapper.find(Foo).state('name') // this breaks! state() can only be called on the root!
})

Таким образом, не совсем уверен, как получить доступ к состоянию локального компонента при использовании <MemoryRouter>.

Возможно я выполняю невежественный тест? Является ли попытка получить/установить состояние компонента плохой практикой при тестировании? Я не могу себе это представить, так как Enzyme имеет методы для получения/установки состояния компонента.

Просто не уверен, как можно получить доступ к внутренним компонентам компонента, <MemoryRouter> в <MemoryRouter>.

Любая помощь будет принята с благодарностью!

Ответ 1

Итак, кажется, что с помощью последней версии Enzyme существует потенциальное исправление этой проблемы доступа к состоянию дочернего компонента.

Скажем, имеем <Foo> (обратите внимание на использование React Router <Link>)

class Foo extends Component {
  state = {
    bar: 'here is the state!'
  }

  render () {
    return (
      <Link to='/'>Here is a link</Link>
    )
  }
}

Примечание. Следующий код доступен только в Enzyme v3.

Пересмотр тестового кода, теперь мы можем написать следующие

it('puts the lotion in the basket', () => {
  const wrapper = mount(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  expect(wrapper.find(Foo).instance().state).toEqual({
    bar: 'here is the state!'
  })
})

Используя wrapper.find(Child).instance(), мы можем получить доступ к состоянию Child, даже если это вложенный компонент. В предыдущих версиях Enzyme мы могли получить доступ только к instance в корне. Вы также можете вызвать функцию setState в обертке Child!

Мы можем использовать аналогичную модель с нашими неглубоко оцениваемыми тестами

it('puts the lotion in the basket shallowly', () => {
  const wrapper = shallow(
    <MemoryRouter>
      <Foo />
    </MemoryRouter>
  )

  expect(wrapper.find(Foo).dive().instance().state).toEqual({
    bar: 'here is the state!'
  })
})

Обратите внимание на использование dive в неглубоком тесте, который может быть запущен на одном, не DOM node и вернет node, мелкорежущий.


Refs:

Ответ 2

Думаю, это может быть полезно для вас, ребята, так как я наткнулся на это и исправлю.

В моем случае у меня есть компонент, который связан с Redux.

class ComponentName extends Component {
...
}
export default connect(
  mapStateToProps,
  {
...
 }
)(ComponentName );

connect(), очевидно, является компонентом HOC. Итак, как нам получить доступ к "ComponentName" здесь?

Очень просто:

component
    .find(ComponentName)
    .children()
    .first()
    .props() // returns ComponentName props