我有以下组件:
class PlayButton extends Component {
constructor () {
super();
this.state = { glow: false };
this.play = this.play.bind(this);
}
componentDidUpdate () {
if (this.props.media.currentTime === 0 && this.props.media.duration !== 0 && !this.state.glow) {
console.log('entering')
setTimeout(() => {
console.log('did time out')
this.setState({ glow: true });
}, 3000);
}
if (this.props.media.currentTime !== 0 && this.state.glow) {
this.setState({ glow: false });
}
}
我想测试componentDidMount中的setState但是无法完成它:
it('button shoould start glowing', () => {
const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }}/>);
wrapper.update()
jest.runAllTimers();
expect(wrapper.state('glow')).toBe(true);
});
有什么想法? 谢谢!
答案 0 :(得分:1)
好吧,这就是我解决它的方式:
it('button shoould start glowing', () => {
let clock = sinon.useFakeTimers();
const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }}/>);
wrapper.update()
clock.tick(3000)
expect(wrapper.state('glow')).toBe(true);
});
答案 1 :(得分:0)
您可以传入setTimeout
的模拟,而不是立即调用回调:
static defaultProps = {
timeout: setTimeout
}
this.props.timeout(() => {
console.log('did time out')
this.setState({ glow: true });
}, 3000);
it('button shoould start glowing', () => {
const wrapper = mount(<PlayButton media={{ currentTime: 0, duration: 1 }}
timeout={(fn, _) => fn()}}/>);
wrapper.update()
jest.runAllTimers();
expect(wrapper.state('glow')).toBe(true);
});
答案 2 :(得分:0)
调用runAllTimers
后,您必须更新包装器。
查看这篇文章,对我来说https://medium.com/@DavideRama/testing-async-setstate-in-react-settimeout-in-componentdidmount-434602abd7db
const items = ['die Straße', 'die Adresse', 'die Nationalität'];
jest.useFakeTimers();
describe('<DelayedList />', () => {
test('it renders the items with delay', () => {
const component = shallow(
<DelayedList items={items} />
);
jest.runAllTimers();
component.update(); // <--- force re-render of the component
expect(component.state().currentIndex).toEqual(items.length);
expect(component).toMatchSnapshot();
});
});