reactjs - 如何测试从 mapDispatchToProps 传递的函数(React/Redux/Enzyme/Jest)
问题描述
我想测试在模拟按钮单击时调用了从 mapDispatchToProps 传递的函数。
如何测试调用从 mapDispatchToProps 传递的函数?
我试图通过道具传递一个模拟函数,但它不起作用。任何帮助将不胜感激。
下面是我的假类代码和测试示例。
我的组件
// 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?
});
});
});
});
解决方案
我建议按照文档中描述的方法,将连接的组件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
提供测试组件本身所需的一切。(甚至从v3开始shallow
调用 React 生命周期方法)Enzyme
正如您所发现的,要对组件进行完整渲染,需要一个模拟redux
存储并将组件包装在一个Provider
. 除了增加很多复杂性之外,这种方法最终还会在组件单元测试期间测试模拟存储和所有子组件。
我发现直接测试组件,导出并直接测试更有效,mapStateToProps()
这mapDispatchToProps()
很容易,因为它们应该是纯函数。
上面代码中的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,并且非常简单地测试组件将通过传递给的纯函数(或对象)传递正确的 props connect()
。
这确保了单元测试简单且有针对性。可以在测试中测试该组件connect()
及其redux
在完整 DOM 渲染中的所有子组件是否正常工作e2e
。
推荐阅读
- r - 从 randomForest R 中的树中排除变量组合
- r - 以变量为矩阵元素的矩阵代数
- r - 从数字矩阵中删除 '%'
- objective-c - Objective C 中的“for in”协议
- azure-devops - 在 Azure DevOps 中同时选择 Xml 转换和变量替换时不起作用
- python - Kivy:如何使用 2 个列制作 RecycleGridLayout:
- python-3.x - Django 3 Python 3.8 whitenoise 不服务 request.user
- python - scipy gaussian_kde 根据使用的方法产生不同的结果(权重与无权重)
- javascript - 我可以在 Keycloak 注册页面上加载已经写好的电子邮件吗?
- php - 尝试在使用会话变量时获取非对象的属性“页面”