Jest / Enzyme - 没有在React Redux容器上设置道具

时间:2017-11-27 18:26:21

标签: unit-testing react-redux enzyme jest

我是Jest / Enzyme和React的新手,我正在尝试测试容器组件。

我的测试是检查道具匹配的是initialState。

这是我的组件

import React, { Component } from 'react';
import { connect } from 'react-redux';

import { loadHomeAction } from '../../actions/home';

export class Home extends Component {
  componentDidMount() {
    this.props.dispatch(loadHomeAction());
  }

  render() {
    const { content, loading } = this.props.home;
    return (
      <div>
        <div>{loading && <p>Loading...</p>}</div>
        <div>{!loading && content.map(item => <p key={item.message}>{item.message}</p>)}</div>
      </div>
    );
  }
}

const mapStateToProps = ({ home }) => ({ home });

export default connect(mapStateToProps)(Home);

这是我的测试

import React from 'react';
import { shallow, mount, configure } from 'enzyme';
import renderer from 'react-test-renderer';
import Adapter from 'enzyme-adapter-react-16';

import configureStore from 'redux-mock-store';
import { Provider } from 'react-redux';
import { createStore } from 'redux';

import App from '../../App';
import ConnectedHome, { Home } from './';

configure({ adapter: new Adapter() });

describe('HOME', () => {
  it('should render the DUMB component', () => {
    const { wrapper } = setup(defaultProps);
    expect(wrapper.length).toEqual(1);
  });

  it('should display the initial loading message', () => {
    const { wrapper } = setup(defaultProps);
    expect(wrapper.contains('Loading...')).toEqual(true);
  });
});

describe('CONNECTED HOME', () => {
  it('should render the SMART component', () => {
    const { container } = setup(defaultProps, initialState);
    expect(container.length).toEqual(1);
  });

  it('should match props with initial state', () => {
    const { container } = setup(defaultProps, initialState);
    expect(container.prop('home')).toEqual(initialState);
  });
});

const initialState = {
  content: [],
  loading: true,
  error: null
};

const defaultProps = {
  home: {
    content: [],
    loading: true,
    error: null
  },
  dispatch: () => {}
};

function setup(props = {}, state = {}) {
  const mockStore = configureStore();
  const store = mockStore(state);

  const wrapper = shallow(<Home {...props} />);
  const container = shallow(<ConnectedHome store={store} />);

  return { wrapper, container };
}

目前,所有测试都在通过,should match props with initial state除外 - 此测试返回:

 CONNECTED HOME › should match props with initial state

    expect(received).toEqual(expected)

    Expected value to equal:
      {"content": [], "error": null, "loading": true}
    Received:
      undefined

    Difference:

      Comparing two different types of values. Expected object but received undefined.

在注销容器时,我可以看到主页未定义。

我对如何/为何不起作用感到困惑。

我一直关注此博客文章,试图了解测试这些连接的组件 - https://medium.com/netscape/testing-a-react-redux-app-using-jest-and-enzyme-b349324803a9

修改

好的,所以我对我的测试进行了一些更改,我的设置功能现在看起来像

function setup(props = {}, state = {}) {
  const mockStore = configureStore();
  const store = mockStore(state);

  const wrapper = shallow(<Home {...props} />);
  const container = shallow(
    <Provider store={store}>
      <ConnectedHome />
    </Provider>
  );

  return { wrapper, container };
}

我的测试看起来像

  it('should match props with initial state', () => {
    const { container } = setup({}, initialState);

    expect(container.props().home).toEqual(initialState);
  });

现在我从控制台得到这个

TypeError: Cannot destructure property `content` of 'undefined' or 'null'.
编辑#2。编辑#2 通过添加<ConnectedHome {...props} />我的测试现在有效。然而,我觉得我基本上说的是1 = 1。

1 个答案:

答案 0 :(得分:0)

在我看来,你不应该只为了让它可测试而导出一个类。我发布了一个更简洁的解决方案作为类似问题的答案。请看这里:How to Unit Test React-Redux Connected Components?

另外,为了回答你的问题,我的建议是:

  1. 使用snapshot testing测试渲染方法。
  2. 分别测试componentDidMount方法。
  3. 如何测试componentDidMount呢?你走了:

    &#13;
    &#13;
    it('componentDidMount should dispatch loadHomeAction', () => {
      const wrapper = shallow(<Home dispatch={jest.fn()} />);
      wrapper.instance().componentDidMount();
      expect(wrapper.instance().props.dispatch).toBeCalledWith(loadHomeAction());
    });
    &#13;
    &#13;
    &#13;