在 componentDidMount 中测试 setTimeout 的执行?
Test execution of setTimeout inside componentDidMount?
我有以下组件:
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);
});
有什么想法吗?
谢谢!
您可以传入 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);
});
好吧,我是这样解决的:
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);
});
您必须在调用 runAllTimers
后更新包装器。
检查这个 post,它对我来说很好 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();
});
});
我有以下组件:
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);
});
有什么想法吗? 谢谢!
您可以传入 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);
});
好吧,我是这样解决的:
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);
});
您必须在调用 runAllTimers
后更新包装器。
检查这个 post,它对我来说很好 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();
});
});