如何为调用 reduxjs 的 mapStateToProps 的反应组件编写单元测试?
Posted
技术标签:
【中文标题】如何为调用 reduxjs 的 mapStateToProps 的反应组件编写单元测试?【英文标题】:How can I write a unit test for a react component that calls reduxjs's 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 <Provider>, 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
操作。
我想要做的事情可以实现吗?我这样做的方式是否正确?
【问题讨论】:
【参考方案1】:我在一些地方看到的建议是测试非连接组件,而不是连接版本。因此,请验证当您将特定道具传递给组件时,您会获得预期的渲染输出,并验证当您传入具有特定形状的状态时,您的 mapStateToProps()
会返回预期的片段。然后你可以期望它们放在一起时应该都能正常工作。
【讨论】:
Redux 文档在 redux.js.org/docs/recipes/WritingTests.html 中明确建议了这一点。其他文章中也有一些相关的例子,比如Simple React/Redux Testing和Unit Testing a Redux App 谢谢,redux 文档对这个问题真的很清楚。我自己应该看到的。 您最终可能会遇到正在测试未连接组件的情况......但在一个相当复杂的应用程序中,可以连接该未连接组件的 -children-。所以它并不总是那么简单(除非只连接您的***组件)。除了模拟导入之外,还没有找到一个好的解决方案。 @shados 你尝试过这样的事情吗?expect(result.type).to.equal(ConnectedChildComponent)
其中ConnectedChildComponent
是导入的连接组件 - 请注意,您不是在检查字符串或<Element/>
,而是在导出的connect(...)(YourComponent)
元素上。
@shados 你能找到一种方法来正确测试嵌套连接组件的连接组件吗?以上是关于如何为调用 reduxjs 的 mapStateToProps 的反应组件编写单元测试?的主要内容,如果未能解决你的问题,请参考以下文章
使用 @reduxjs/toolkit 中的 configureStore 时如何重置 Redux Store 的状态?