【问题标题】:React js unit tests for connected components - mocha用于连接组件的 React js 单元测试 - mocha
【发布时间】:2017-05-16 08:55:46
【问题描述】:

我有一个智能组件,正在尝试编写单元测试(DOM 测试) - 收到以下错误:不知道为什么我会收到此错误,即使我在测试中传递了道具..?

Invariant Violation:在“Connect(myComponent)”的上下文或道具中找不到“store”。要么将根组件包装在 a ,或显式将“store”作为道具传递给 “连接(我的组件)”。

更新了新错误:TypeError: Cannot read property 'mainData' of undefined at 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 是一个哑组件的子组件

我的组件代码:

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);

【问题讨论】:

    标签: reactjs redux mocha.js react-redux enzyme


    【解决方案1】:

    错误清楚地表明,MyComponent 使用来自reduxconnect 连接到商店。因此,当您使用TestUtils.renderIntoDocument(&lt;myComponent {...props} /&gt;);

    组件尝试使用 redux 来获取需要提供的 store。您需要创建一个测试存储,以便您连接的组件接收减速器。

    例子:

    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的连接组件添加provider和store。

    更新 Actions may not have an undefined "type" property 是因为在myComponent 中,connect 方法没有执行操作。您能否将您的整个代码发布为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);
    

    【讨论】:

    • 感谢您的帮助,更新了我的代码,但我收到了一个新错误 - 我已经用最新的代码更新了我的问题 - TypeError: Cannot read property 'mainData' of undefined, mainData 是我的确切词在我的组件中使用 - 我传递道具对吗? @stackoverflow.com/users/308565/nagaraj-tantri
    • 更新了答案,因为你需要来自redux状态的mainData,你不能将它作为props传递,你需要在mockStore中初始化它,比如:const initialState = { mainData: DataMock, userID: '1' };然后@987654336 @
    • 试过但同样的错误 - 我刚刚更新了 myComponent 的代码 - mainData:state.reducerName.mainData,这里的问题与reducername有关吗?因为错误说组件中未定义的 mainData - 如何从测试用例中处理这个? stackoverflow.com/users/308565/nagaraj-tantri
    • @monkeyjs 是的,因为,对象嵌套很深。现在,如果您的mainDatareducerName 内,那么请确保您的测试数据也是类似的键值结构。所以,const initialState = { reducerName: { mainData: DataMock } };
    • 我收到错误:操作可能没有未定义的“类型”属性。你有没有拼错一个常数?行动:在 Object. actioncreatorfuncone (node_modules/redux/lib/bindActionCreators.js:7:12) - 我应该做这样的事情 - const action = { types: 'ADD_ITEM' }
    【解决方案2】:

    我正在做的一种方法是单独导出组件以进行如下测试。

    export class MyComponent extends Component {
      // your stuff here
    } 
    
    export default connect(mapStateToProps, actions)(MyComponent);
    

    这里我们将导入没有redux wrapper的组件进行测试

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

    供参考Testing Redux Component

    注意:我们必须将所需的道具传递给组件。

    【讨论】:

      猜你喜欢
      • 2018-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-22
      • 1970-01-01
      • 1970-01-01
      • 2016-05-09
      相关资源
      最近更新 更多