简体   繁体   English

测试连接的Redux组件时的提示

[英]Tips when testing a connected Redux Component

I've pasted my Component below which is very, very basic. 我在下面非常非常基础地粘贴了我的组件。 When the Component is mounted, it will basically call the fetchMessage Action, which returns a message from an API. 挂载组件后,它将基本上调用fetchMessage操作,该操作从API返回一条消息。 That message will in turn get set as state.feature.message in the mapStateToProps function. 该消息将依次在mapStateToProps函数中设置为state.feature.message

I'm at a complete loss on where to begin testing this Component. 我完全不知从哪里开始测试此组件。 I know that I want to test that: 我知道我想测试一下:

1) The Feature Component is rendered 1)渲染特征组件

2) The fetchMessage function in props is called 2)调用propsfetchMessage函数

3) It displays or has the correct message property when rendered using that 3)使用该属性渲染时显示或具有正确的message属性

I've tried setting my test file up as you can see below, but I just end up with repeated error after error with everything that I try. 我已经尝试设置测试文件,如下所示,但是最终我遇到的所有尝试都一次又一次出错。

Could anyone point me in the right direction with what I'm doing wrong? 有人能指出我做错了正确的方向吗?

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

class Feature extends Component {
  static propTypes = {
    fetchMessage: PropTypes.func.isRequired,
    message: PropTypes.string
  }

  componentWillMount() {
    this.props.fetchMessage();
  }

  render() {
    return (
      <div>{this.props.message}</div>
    );
  }
}

function mapStateToProps(state) {
  return { message: state.feature.message };
}

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

Test file: 测试文件:

import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import expect from 'expect';
import { shallow, render, mount } from 'enzyme';
import React from 'react';
import sinon from 'sinon';

import Feature from '../index';

const mockStore = configureStore([thunk]);

describe('<Feature />', () => {
  let store;

  beforeEach(() => {
    store = mockStore({
      feature: {
        message: 'This is the message'
      }
    });
  });

  it('renders a <Feature /> component and calls fetchMessage', () => {
    const props = {
      fetchMessage: sinon.spy()
    };

    const wrapper = mount(
      <Provider store={store}>
        <Feature {...props} />
      </Provider>
    );

    expect(wrapper.find('Feature').length).toEqual(1);
    expect(props.fetchMessage.calledOnce).toEqual(true);
  });
});

Testing Connected React Components 测试连接的React组件

Use separate exports for the connected and unconnected versions of the components. 对组件的已连接和未连接版本使用单独的导出。

Export the unconnected component as a named export and the connected as a default export. 将未连接的组件导出为命名导出,将已连接的组件导出为默认导出。

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

// export the unwrapped component as a named export
export class Feature extends Component {
  static propTypes = {
    fetchMessage: PropTypes.func.isRequired,
    message: PropTypes.string
  }

  componentWillMount() {
    this.props.fetchMessage();
  }

  render() {
    return (
      <div>{this.props.message}</div>
    );
  }
}

function mapStateToProps(state) {
  return { message: state.feature.message };
}

// export the wrapped component as a default export
export default connect(mapStateToProps, actions)(Feature);

Remember connected components must be wrapped in a Provider component as shown below. 请记住, 连接的组件必须包装在Provider组件中 ,如下所示。

Whereas unconnected components can be tested in isolation as they do not need to know about the Redux store. 而未连接的组件可以进行隔离测试,因为它们不需要了解Redux存储。

Test file: 测试文件:

import configureStore from 'redux-mock-store';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import expect from 'expect';
import { shallow, render, mount } from 'enzyme';
import React from 'react';
import sinon from 'sinon';

// import both the wrapped and unwrapped versions of the component
import ConnectedFeature, { feature as UnconnectedFeature } from '../index';

const mockStore = configureStore([thunk]);

describe('<Feature />', () => {
  let store;

  beforeEach(() => {
    store = mockStore({
      feature: {
        message: 'This is the message'
      }
    });
  });

  it('renders a <Feature /> component and calls fetchMessage', () => {
    const props = {
      fetchMessage: sinon.spy()
    };

    const wrapper = mount(
      <Provider store={store}>
        <connectedFeature {...props} />
      </Provider>
    );

    expect(wrapper.find('Feature').length).toEqual(1);
    expect(props.fetchMessage.calledOnce).toEqual(true);
  });
});

You can use shallow() instead of mount() to test your component. 您可以使用shallow()代替mount()来测试组件。 The shallow() method calls the componentWillMount() life-cycle method so there is no reason to use mount() . shallow()方法调用componentWillMount()生命周期方法,因此没有理由使用mount() ( Disclaimer: I am not quite well at mount() yet.) 免责声明:我对mount()不太满意。)

For connected components, you can pass a store object like this: 对于连接的组件,可以像这样传递存储对象:

<connectedFeature {...props} store={store} />

And you should call shallow() method twice to make it work for connected components: 您应该两次调用shallow()方法以使其适用于连接的组件:

const wrapper = shallow(<connectedFeature {...props} store={store} />).shallow()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM