如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)
Posted
技术标签:
【中文标题】如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)【英文标题】:How to test function that passed from mapDispatchToProps (React/Redux/Enzyme/Jest) 【发布时间】:2019-02-03 22:41:03 【问题描述】:我想测试在模拟按钮单击时调用了从 mapDispatchToProps 传递的函数。
如何测试从 mapDispatchToProps 传递的函数被调用?
我试图通过 props 传递一个模拟函数,但它不起作用。任何帮助将不胜感激。
下面是我的假类代码和测试示例。
我的组件
// All required imports
class App extends React.Component<Props>
render()
const onClick = this.props;
return (
<>
<h1>Form</h1>
<input />
<button onClick=() => onClick() />
</>
);
const mapStateToProps = (state) =>
return
state
;
;
const mapDispatchToProps = (dispatch) =>
return
onClick: () => dispatch(actions.onClick())
;
;
export default connect(mapStateToProps, mapDispatchToProps)(App);
我的测试文件
import configure, mount from 'enzyme';
import Adapter from 'enzyme-adapter-react-16/build/index';
import jsdom from 'jsdom';
import React from 'react';
import Provider from 'react-redux';
import configureMockStore from 'redux-mock-store';
import ConnectedApp, App from './App';
function setUpDomEnvironment()
const JSDOM = jsdom;
const dom = new JSDOM('<!doctype html><html><body></body></html>', url: 'http://localhost/' );
const window = dom;
global.window = window;
global.document = window.document;
global.navigator =
userAgent: 'node.js',
;
copyProps(window, global);
function copyProps(src, target)
const props = Object.getOwnPropertyNames(src)
.filter(prop => typeof target[prop] === 'undefined')
.map(prop => Object.getOwnPropertyDescriptor(src, prop));
Object.defineProperties(target, props);
setUpDomEnvironment();
configure( adapter: new Adapter() );
const mockStore = configureMockStore();
describe('App', () =>
describe('When App connected to store', () =>
describe('When button clicked', () =>
it('should not crush after click on login button', () =>
const onClick = jest.fn()
const store = mockStore(initialStates[1]);
const wrapper = mount(
<Provider store=store>
<ConnectedApp />
</Provider>);
wrapper.find('button').simulate('click');
??? how to test that function passed from mapDispatchToProps was fired?
);
);
);
);
【问题讨论】:
你不能只检查状态对象以确保更改是从操作中进行的吗? 【参考方案1】:我建议关注the approach described in the docs 并将连接的组件导出为default
导出以在应用程序中使用,并将组件本身导出为命名导出以进行测试。
对于export
上面的代码App
类并像这样测试点击:
import * as React from 'react';
import shallow from 'enzyme';
import App from './code';
describe('App', () =>
it('should call props.onClick() when button is clicked', () =>
const onClick = jest.fn();
const wrapper = shallow(<App onClick=onClick />);
wrapper.find('button').simulate('click');
expect(onClick).toHaveBeenCalledTimes(1);
);
);
shallow
提供了测试组件本身所需的一切。 (shallow
even calls React lifecycle methods Enzyme
v3)
正如您所发现的,要对组件进行完整渲染,需要模拟 redux
存储并将组件包装在 Provider
中。除了增加很多复杂性之外,这种方法最终还会在组件单元测试期间测试模拟存储和所有子组件。
我发现直接测试组件更有效,导出并直接测试mapStateToProps()
和mapDispatchToProps()
非常简单,因为它们应该是pure functions。
上面代码中的mapDispatchToProps()
可以这样测试:
describe('mapDispatchToProps', () =>
it('should dispatch actions.onClick() when onClick() is called', () =>
const dispatch = jest.fn();
const props = mapDispatchToProps(dispatch);
props.onClick();
expect(dispatch).toHaveBeenCalledWith(actions.onClick());
);
);
这种方法使得对组件进行单元测试非常简单,因为您可以直接传递组件 props,并且非常简单地测试组件将由传递给 @987654338 的纯函数 (or objects) 传递正确的 props @。
这可确保单元测试简单且有针对性。可以在 e2e
测试中测试 connect()
和 redux
是否与组件及其所有子组件在完整 DOM 渲染中正常工作。
【讨论】:
以上是关于如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 React-Testing-Library 测试 mapDispatchToProps?
使用 Jest/Enzyme 测试异步 mapDispatchToProps 操作会出错
React Redux:使用 Enzyme/Jest 测试 mapStateToProps 和 mapDispatchToProps