Модульные тесты React js для подключенных компонентов - mocha

У меня есть интеллектуальный компонент, пытающийся написать модульный тест (тесты DOM) - появляется следующая ошибка: Не уверен, почему я получаю эту ошибку, даже если я передаю реквизиты в тесте ..?

Неизменяемое нарушение: не удалось найти "store" ни в контексте, ни в свойствах "Connect (myComponent)". Либо оберните корневой компонент в a, либо явно передайте «store» в качестве опоры для «Connect (myComponent)».

Обновленная новая ошибка: TypeError: невозможно прочитать свойство mainData для undefined в mapStateToProps

тестовый код:

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';
import { renderComponent, expect } from '../../test_helper';
import myComponent from '../../../src/containers/myComponent';


describe('myComponent', () => {
  const mockStore = configureMockStore();
  let connectedApp,
    store,
    initialItems;
  let component;
  let componentRender;

  beforeEach(() => {
    const DataMock = [1, 2, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 
      0, 1, 2, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 
      2, 0, 0, 0, 0, 0];

    const props = {
      mainData: DataMock,
      abc: 'def',
      subData: {
        test: '1',
        testing: 12,
      },
      userID: '1',
      Date: 'jan11',
    };

    initialItems = ['one'];
    const initialState = {
      items: initialItems
    };

    store = mockStore(initialState);

    component = TestUtils.renderIntoDocument(
      <Provider store={store}><myComponent {...props} /></Provider>);

    componentRender = ReactDOM.findDOMNode(component);
  });

  it('loads', () => {
    expect(component).to.exist;
  });
});

этот myComponent является дочерним элементом немого компонента

Код myComponent:

import React, { PropTypes, Component } from 'react';
import { connect } from 'react-redux';
import * as actions from '../../actions/component_actions';

class myComponent extends Component {

  constructor(props) {
    super(props);
    this.state = {
      someString: 'abc',
      someotherstring: 'def',
    };
  }

  componentDidMount() {
    const { test1, test2, test3 } = this.props;
    this.props.fetchEntriesDefault(test1, test2, test3);
    this.props.fetchAnalyticsMainView(test1, test2, test3);
  }

render() {
    return (
      <div className="container">
     </div>
   );
  }
 }


    function mapStateToProps(state) {
      return {
        mainData: state.reducerName.mainData,
        subDataData: state.reducerName.subDataData,
      };
    }
    myComponent.propTypes = {
      mainData: PropTypes.array,
      abc: PropTypes.string,
      subDataData: PropTypes.object,
      userID: PropTypes.string,
      actioncreatorfuncone: PropTypes.func,
      actioncreatorfunctwo: PropTypes.func,
      date: PropTypes.string,
    };

    export default connect(mapStateToProps, actions)(myComponent);

person monkeyjs    schedule 02.01.2017    source источник


Ответы (2)


В ошибке четко указано, что MyComponent подключен к магазину с помощью connect из redux. Следовательно, когда вы используете TestUtils.renderIntoDocument(<myComponent {...props} />);

Компонент пытается использовать redux для получения хранилища, которое необходимо предоставить. Вам необходимо создать тестовое хранилище, чтобы подключенный компонент получил редуктор.

Пример:

import React from 'react';
import ReactDOM from 'react-dom';

// IMPORTANT
import { Provider } from 'react-redux';
import configureMockStore from 'redux-mock-store';

import TestUtils from 'react-addons-test-utils';
import { renderComponent, expect } from '../../test_helper';
import MyComponent from '../../../src/containers/myComponent';    

describe('myComponent', () => {
  var mockStore = configureMockStore();
  var connectedApp, store, initialItems;
  let component;
  let componentRender;

  beforeEach(() => {
    const DataMock = [1, 2, 0, 0, 0, 0, 0, 1, 2, 0, 0, 
      0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 
      0, 1, 2, 0, 0, 0, 0, 0
    ];

    const initialState = {
      mainData: DataMock,
      userID: '1'
    };

    store = mockStore(initialState);
  });

  describe('state provided by the store', function() {
    beforeEach(function() {

      component = TestUtils.renderIntoDocument(
        <Provider store={store}><MyComponent /></Provider>);

      componentRender = ReactDOM.findDOMNode(component);
    });

    it('loads', () => {
      expect(component).to.exist;
    });
  });
});

Таким образом, вам нужно добавить поставщика с хранилищем для подключенного компонента с redux.

Обновление Actions may not have an undefined "type" property связано с тем, что в myComponent метод подключения не получает действий. Не могли бы вы опубликовать весь код для myComponent? Действия, которые нужно добавить? Действия должны быть в виде словаря:

Что-то вроде этого примера:

import { connect } from 'react-redux'
import { login } from '../actions/creators/userActionCreators'

function mapStateToProps(state) {
  return {
    mainData: state.reducerName.mainData,
    subDataData: state.reducerName.subDataData,
  };
}

const mapDispatchToProps = (dispatch) => {
   return {
      onSubmitLogin: (id, pass) => dispatch(login(id, pass))
   }
};

// `LoginForm` is being passed, so it would be the "container"
// component in this scenario
export default connect(mapStateToProps, mapDispatchToProps)(myComponent);
person Nagaraj Tantri    schedule 02.01.2017
comment
Спасибо за вашу помощь, обновил мой код, но я получаю новую ошибку - я обновил свой вопрос последним кодом - TypeError: не удается прочитать свойство mainData для undefined, mainData - это точное слово, которое я использую в своем компоненте - я проходя реквизит правильно? @ stackoverflow.com/users/308565/nagaraj-tantri - person monkeyjs; 03.01.2017
comment
Обновлен ответ, так как вам нужно mainData из состояния redux, вы не можете передать его как props, вам нужно инициализировать его в mockStore, например: const initialState = { mainData: DataMock, userID: '1' };, а затем store = mockStore(initialState); - person Nagaraj Tantri; 03.01.2017
comment
попробовал, но с той же ошибкой - я только что обновил код myComponent - mainData: state.reducerName.mainData, связана ли здесь проблема с именем reducername? потому что ошибка говорит mainData of undefined в компоненте - как справиться с этим из тестового примера? stackoverflow.com/users/308565/nagaraj-tantri - person monkeyjs; 03.01.2017
comment
@monkeyjs да, это потому, что объект глубокое гнездо. Теперь, если ваш mainData находится внутри reducerName, убедитесь, что ваши тестовые данные также имеют аналогичную структуру значения ключа. Итак, const initialState = { reducerName: { mainData: DataMock } }; - person Nagaraj Tantri; 03.01.2017
comment
Я получаю сообщение об ошибке: действия могут не иметь свойства неопределенного типа. Вы неправильно написали константу? Действие: не определено при отправке (node_modules / redux-mock-store / lib / index.js: 39: 19) в Object. actioncreatorfuncone (node_modules / redux / lib / bindActionCreators.js: 7: 12) - должен ли я делать что-то вроде этого - const action = {types: 'ADD_ITEM'} - person monkeyjs; 03.01.2017
comment
@monkeyjs нет, MyComponent принимает второй параметр как actions, так что это потому, что фиктивное хранилище не знает, какие действия необходимо указать. всякий раз, когда вы сталкиваетесь с такими препятствиями, используйте debugger внутри кода и используйте инструменты разработчика Chrome, чтобы увидеть, где данные могут быть повреждены :) - person Nagaraj Tantri; 03.01.2017
comment
примерно так - ‹Provider store = {store} actions = {'FETCH_DATA'}› ‹Entries /› ‹/Provider›); ? - person monkeyjs; 03.01.2017
comment
@monkeyjs нет, действия определены в вашем компоненте, а не в тесте и, следовательно, не в <Provider. Пожалуйста, проверьте обновленный ответ. - person Nagaraj Tantri; 03.01.2017
comment
добавлен полный код myComponent - игнорировать несоответствия имени строки, но это вся структура, как у меня есть действия в соединении - stackoverflow.com / users / 308565 / nagaraj-tantri - person monkeyjs; 03.01.2017
comment
@monkeyjs import * as actions from '../../actions/component_actions'; не дает действий для метода подключения. Вот почему вы получаете Action: undefined at dispatch.... Действия должны быть объектом функций, возвращающих чистые объекты. - person Nagaraj Tantri; 04.01.2017

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

export class MyComponent extends Component {
  // your stuff here
} 

export default connect(mapStateToProps, actions)(MyComponent);

Здесь мы импортируем компонент без оболочки redux для тестирования как

import { MyComponent } from '../../../src/containers/myComponent'; 

Для справки Тестирование компонента Redux

Примечание: нам нужно будет передать компоненту необходимые реквизиты.

person duwalanise    schedule 02.01.2017