我是Jest的单元测试新手。该项目具有一个进度指示器组件,该组件使用setInterval作为计时器。我需要进行单元测试,以确保“进度”功能中的“已完成”状态变量在20ms滴答时正确更新。
"react-dom": "^16.8.6",
"react-redux": "^6.0.1",
"react-scripts": "^2.1.3"
progress.js
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core/styles';
import CircularProgress from '@material-ui/core/CircularProgress';
const styles = theme => ({
progress: {
margin: theme.spacing.unit * 2
}
});
class CircularDeterminate extends React.Component {
state = {
completed: 0
};
componentDidMount() {
this.timer = setInterval(this.progress, 20);
}
componentWillUnmount() {
clearInterval(this.timer);
}
progress = () => {
let be = this.state.completed;
console.log('>>>>>> ', this.state.completed);
const { completed } = this.state;
this.setState({ completed: completed >= 100 ? 0 : completed + 1 });
console.log('+++++ ', be, ' ', this.state.completed);
};
render() {
const { classes } = this.props;
if (!this.props.statusCode) {
return (
<div>
<CircularProgress
className={classes.progress}
variant="determinate"
value={this.state.completed}
/>
</div>
);
} else {
return null;
}
}
}
CircularDeterminate.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(styles)(CircularDeterminate);
progressTest.js
import React from 'react';
import { shallow, mount } from 'enzyme';
import Progress from '../progress';
describe('Input Component', () => {
it('update timer', () => {
jest.useFakeTimers();
const wrapper = mount(<Progress />);
wrapper.instance().setState({ completed: 8 });
jest.advanceTimersByTime(41);
wrapper.update();
expect(wrapper.instance().state.completed).toBe(10);
});
});
上面的测试失败了:预期:10,已接收:8。我希望2个滴答(约41毫秒)后,“完成”的值为10。
答案 0 :(得分:0)
上述代码中的一个问题(取决于Jest的假计时器的工作原理,可能是实际的问题,也可能不是实际的问题,但肯定是 a 问题),这是您在打破一条基本规则的React状态:自state updates are asynchronous起,如果您要基于现有状态设置新状态 ,则必须使用缩减形式setState
。所以这是不正确的:
const { completed } = this.state;
this.setState({ completed: completed >= 100 ? 0 : completed + 1 });
console.log('+++++ ', be, ' ', this.state.completed);
这是正确的形式:
this.setState(
({completed}) => ({
completed: completed >= 100 ? 0 : completed + 1
}),
() => {
console.log('+++++ ', be, ' ', this.state.completed);
}
);