Подтвердить что ты не робот

Вложенные компоненты, испытывающие фермент внутри React & Redux

У меня есть компонент SampleComponent, который монтирует другой "подключенный компонент" (т.е. container). Когда я пытаюсь проверить SampleComponent на mount ing (так как мне нужен componentDidMount), я получаю ошибку:

Инвариантное нарушение: не удалось найти "хранилище" в контексте или реквизиты "Connect (ContainerComponent)". Либо оберните корневой компонент в или явно передать "store" в качестве опоры для "Connect (ContainerComponent)".

Какой лучший способ проверить это?

4b9b3361

Ответ 1

В основном я сделал вывод в мой redux store (и Provider) и завернул его в компонент утилиты следующим образом:

export const CustomProvider = ({ children }) => {
  return (
    <Provider store={store}>
      {children}
    </Provider>
  );
};

тогда я mount SampleComponent и выполните тесты против него:

it('contains <ChildComponent/> Component', () => {
  const wrapper = mount(
    <CustomProvider>
      <SampleComponent {...defaultProps} />
    </CustomProvider>
  );
  expect(wrapper.find(ChildComponent)).to.have.length(1);
});

Ответ 2

Ферментное крепление принимает необязательные параметры. Эти два, которые необходимы для того, что вам нужно,

options.context: (Object [optional]): Context to be passed into the component

options.childContextTypes: (Object [optional]): Merged contextTypes for all children of the wrapper Вы бы установили SampleComponent с таким образом:

const store = { 
  subscribe: () => {},
  dispatch: () => {},
  getState: () => ({ ... whatever state you need to pass in ... })
}
const options = {
  context: { store }, 
  childContextTypes: { store: React.PropTypes.object.isRequired } 
}

const _wrapper = mount(<SampleComponent {...defaultProps} />, options)

Теперь ваш SampleComponent передаст контекст, который вы предоставили, до connected component.

Ответ 3

Вы можете использовать экспорт имен для решения этой проблемы:

Вы должны иметь:

class SampleComponent extends React.Component{
...
   render(){
       <div></div>
   }
}

export default connect(mapStateToProps, mapDispatchToProps)(SampleComponent)

Вы можете добавить экспорт перед классом:

export class SampleComponent extends React.Component{

и импортируйте этот компонент без хранилища redux:

import { SampleComponent } from 'your-path/SampleComponent';

С помощью этого решения вам не нужно импортировать хранилище в тестовые файлы.

Ответ 4

Вариант 1). Вы можете обернуть компонент контейнера компонентом поставщика React-Redux в своем тесте. Таким образом, при таком подходе вы фактически обращаетесь в магазин, передаете его Поставщику и составляете свой компонент под тестом внутри. Преимущество такого подхода заключается в том, что вы можете создать собственный магазин для теста. Этот подход полезен, если вы хотите протестировать связанные с Redux части вашего компонента. Вариант 2) Возможно, вам не нужно тестировать части, связанные с Redux. Если вам просто интересно тестировать рендеринг компонентов и поведение, связанное с локальным состоянием, вы можете просто добавить именованный экспорт для несвязанной простой версии вашего компонента. И просто чтобы уточнить, когда вы добавляете ключевое слово "экспорт" в свой класс, в основном вы говорите, что теперь класс может быть импортирован двумя способами либо с фигурными фигурными скобками {}, либо нет. Пример:

export class MyComponent extends React.Component{ render(){ ... }}

...

export default connect(mapStateToProps, mapDispatchToProps)(MyComponent)

позже в тестовом файле:

import MyComponent from 'your-path/MyComponent'; // it needs a store because you use "default export" with connect
import {MyComponent} from 'your-path/MyComponent'; // don't need store because you use "export" on top of your class.

Я надеюсь, что кто-то там поможет.