【问题标题】:How can I write a unit test for a react component that calls reduxjs's mapStateToProps?如何为调用 reduxjs 的 mapStateToProps 的反应组件编写单元测试?
【发布时间】:2016-04-09 06:43:36
【问题描述】:

我正在尝试为名为 AsyncApp 的容器组件编写单元测试,但我收到以下错误“mapStateToProps 必须返回一个对象。而是收到未定义。”

这是我的设置。

Root.js

import configureStore from '../configureStore';
import React, { Component } from 'react';
import { Provider } from 'react-redux';
import AsyncApp from './AsyncApp';

const store = configureStore();

export default class Root extends Component {
  render() {
    return (
      <Provider store={store}>
        <AsyncApp />
      </Provider>
    );
  }
}

configureStore.js

import { createStore, applyMiddleware } from 'redux';
import thunkMiddleware from 'redux-thunk';
import createLogger from 'redux-logger';
import rootReducer from './reducers';

const loggerMiddleware = createLogger();

const createStoreWithMiddleware = applyMiddleware(
  thunkMiddleware
  //loggerMiddleware
)(createStore);

export default function configureStore(initialState) {
  return createStoreWithMiddleware(rootReducer, initialState);
}

AsyncApp.js

import React, { Component, PropTypes } from 'react';
import { connect } from 'react-redux';
import { foo } from '../actions';
import FooComponent from '../components/FooComponent';

class AsyncApp extends Component {
  constructor(props) {
    super(props);
    this.onFoo= this.onFoo.bind(this);
    this.state = {}; // <--- adding this doesn't fix the issue
  }

  onFoo(count) {
    this.props.dispatch(foo(count));
  }

  render () {
    const {total} = this.props;

    return (
      <div>
        <FooComponent onFoo={this.onFoo} total={total}/>
      </div>
    );
  }
}

function mapStateToProps(state) {
  return state;
}

export default connect(mapStateToProps)(AsyncApp);

我在测试中将store 直接传递给AsyncApp,以避免出现以下运行时错误:Could not find "store" in either the context or props of "Connect(AsyncApp)". Either wrap the root component in a &lt;Provider&gt;, or explicitly pass "store" as a prop to "Connect(AsyncApp)".

测试尚未完成,因为我无法通过 mapStateToProps 错误消息。

AsyncApp-test.js

jest.dontMock('../../containers/AsyncApp');
jest.dontMock('redux');
jest.dontMock('react-redux');
jest.dontMock('redux-thunk');
jest.dontMock('../../configureStore');

import React from 'react';
import ReactDOM from 'react-dom';
import TestUtils from 'react-addons-test-utils';
const configureStore = require( '../../configureStore');
const AsyncApp = require('../../containers/AsyncApp');

const store = configureStore();

//const asyncApp = TestUtils.renderIntoDocument(
  //<AsyncApp store={store} />
//);

const shallowRenderer = TestUtils.createRenderer();
shallowRenderer.render(<AsyncApp store={store}/>);

我想最终测试AsyncApp 是否包含FooComponent,并且在调用onFoo 时会调度foo 操作。

我想要做的事情可以实现吗?我这样做的方式是否正确?

【问题讨论】:

    标签: javascript reactjs redux jestjs


    【解决方案1】:

    我在一些地方看到的建议是测试非连接组件,而不是连接版本。因此,请验证当您将特定道具传递给组件时,您会获得预期的渲染输出,并验证当您传入具有特定形状的状态时,您的 mapStateToProps() 会返回预期的片段。然后你可以期望它们放在一起时应该都能正常工作。

    【讨论】:

    • Redux 文档在 redux.js.org/docs/recipes/WritingTests.html 中明确建议了这一点。其他文章中也有一些相关的例子,比如Simple React/Redux TestingUnit Testing a Redux App
    • 谢谢,redux 文档对这个问题真的很清楚。我自己应该看到的。
    • 您最终可能会遇到正在测试未连接组件的情况......但在一个相当复杂的应用程序中,可以连接该未连接组件的 -children-。所以它并不总是那么简单(除非只连接您的顶级组件)。除了模拟导入之外,还没有找到一个好的解决方案。
    • @shados 你尝试过这样的事情吗? expect(result.type).to.equal(ConnectedChildComponent) 其中ConnectedChildComponent 是导入的连接组件 - 请注意,您不是在检查字符串或&lt;Element/&gt;,而是在导出的connect(...)(YourComponent) 元素上。
    • @shados 你能找到一种方法来正确测试嵌套连接组件的连接组件吗?
    猜你喜欢
    • 2022-10-19
    • 2017-10-15
    • 1970-01-01
    • 1970-01-01
    • 2018-10-30
    • 1970-01-01
    • 2010-11-16
    • 2020-03-02
    • 1970-01-01
    相关资源
    最近更新 更多