reactjs - 为在 Enzyme 中模拟 onClick 事件编写测试用例?
问题描述
HeaderBar.jsx
我想在文件中编写测试用例HeaderBar.spec.jsx
。
首先,我想编写测试用例来检查我history.push()
正在执行的调用,然后我想检查是否history.push()
使用mockURL
.
history.push()
发现于onLogout()
这是HeaderBar.jsx
import React from 'react';
import { PropTypes } from 'prop-types';
import { bindActionCreators } from 'redux';
import { makeStyles } from '@material-ui/core/styles';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Typography from '@material-ui/core/Typography';
import Button from '@material-ui/core/Button';
import IconButton from '@material-ui/core/IconButton';
import MenuIcon from '@material-ui/icons/Menu';
import { connect } from 'react-redux';
import { withTranslation } from 'react-i18next';
import { ROUTE_CONSTANTS, I18N_CONSTANTS } from '../../../../constants';
import { commonAction, sessionAction } from '../../../../redux/actions';
const useStyles = makeStyles(theme => ({
root: {
flexGrow: 1
},
menuButton: {
marginRight: theme.spacing(2)
},
title: {
flexGrow: 1
}
}));
const HeaderBar = ({ history, t, actions }) => {
const classes = useStyles();
const onLogout = () => {
history.push(ROUTE_CONSTANTS.MEMBER.LOGOUT);
actions.logout();
};
// const onLogout = () => { throw new Error('Failed to run') };
return (
<div className={classes.root}>
<AppBar position="static" color="default">
<Toolbar>
<IconButton edge="start" className={classes.menuButton} color="inherit" aria-label="menu">
<MenuIcon />
</IconButton>
<Typography variant="h6" className={classes.title}>
{t('headerBar.title')}
</Typography>
<Button color="inherit" onClick={onLogout}>
{t('headerBar.logout')}
</Button>
</Toolbar>
</AppBar>
</div>
);
};
HeaderBar.defaultProps = {
t: () => {},
history: {
push: () => {}
}
};
const mapStateToProps = state => {
return {
isLoading: state.common.loadingIndicator.isLoading
};
};
const mapDispatchToProps = dispatch => {
return {
actions: bindActionCreators({ ...commonAction, ...sessionAction }, dispatch)
};
};
HeaderBar.propTypes = {
actions: PropTypes.shape({
logout: PropTypes.func.isRequired
}).isRequired,
t: PropTypes.func,
history: PropTypes.shape({
push: PropTypes.func
})
};
const component = connect(mapStateToProps, mapDispatchToProps)(HeaderBar);
export default withTranslation(I18N_CONSTANTS.NAMESPACE.APP)(component);
HeaderBar.spec.jsx
import React from 'react';
import { mount } from 'enzyme';
import { Provider } from 'react-redux';
import configureStore from '../../../../redux/store/configureStore';
import HeaderBar from './HeaderBar';
const setup = (props = {}) => {
const store = configureStore();
window.location.replace = jest.fn();
const defaultProps = {
isLoading: false,
history: {
replace: jest.fn(x => x)
},
...props
};
return mount(
<Provider store={store}>
<HeaderBar {...defaultProps} />
</Provider>
);
};
describe('HeaderBar component', () => {
it('should call translation 2 times', () => {
const props = { t: jest.fn() };
const wrapper = setup(props);
const { t, isLoading } = wrapper.find('HeaderBar').props();
expect(t).toHaveBeenCalledTimes(2);
expect(isLoading).toBeFalsy();
});
it('should call history on onClick event', () => {
const props = { history: { replace: jest.fn(x => x) }, onLogout: jest.fn(x => x) };
const wrapper = setup(props);
// console.log(wrapper.find('button').debug());
wrapper.find('button').simulate('click');
expect(props.history.replace).toHaveBeenCalledTimes(1);
});
it('should call history with mock URL', () => {
const props = { history: { replace: jest.fn(x => x) } };
const wrapper = setup(props);
const mockURL = '/';
wrapper
.find('button')
.at(0)
.simulate('click');
expect(props.history.replace).toHaveBeenCalledWith(mockURL);
});
});
should call history on onClick event
并且should call history with mock URL
不适合我。
请帮我解决这个问题。
解决方案
- 您模拟 history.replace,但在您的组件中使用 history.push。
- 您将函数的实现模拟为 (x => x),但这些函数实际上不接收任何参数。
- 您的注销按钮真的是这个包装器的 DOM 中唯一的吗?也许添加一些ID?
推荐阅读
- sql - 使用动态 SQL 在一个参数中执行多列通配符搜索
- python-3.x - ec2client.describe_instances 在向 IAM 策略添加条件后返回 UnauthorizedOperation
- netsuite - Netsuite itemFulfillment search where status = Pick
- flutter - 如何用颤振罗盘找方向?
- android - 从 textView 获取 int
- haskell - 如何从每个可能的字符中生成字符串?
- reactjs - c.getBoundingClientRect 不是函数
- string - ESP8266 无法将字符添加到非常长的字符串(> 8000 个字符)
- python - 使用pyspark分区时循环覆盖模式
- acumatica - 如何在 Acumatica 移动应用程序中获取 GPS 位置?