I was wondering how to test what does interval dependant timer display after a few ticks with React Testing Library and Jest. Assume we have such code:
import React, { Component } from 'react';
let timer;
class Test extends Component {
constructor() {
super();
this.state = {
timeLeft: 60
}
}
componentDidMount() {
this.handleTick();
}
componentDidUpdate() {
const { timeLeft } = this.state;
if (!timeLeft) {
clearInterval(timer);
this.setState({
timeLeft: 60,
})
}
}
handleTick() {
timer = setInterval(() => {
this.setState({timeLeft: this.state.timeLeft - 1 })
},1000)
}
render() {
return (
<React.Fragment>
<h3>I'm test.</h3>
<h4>{this.state.timeLeft}</h4>
</React.Fragment>
)
}
}
And now in test we want to check if Test component shows exactly what we want after let's say 15 sec. I have tried:
describe('Test Component', () => {
test('Timer should display 45 sec left', () => {
jest.useFakeTimers();
const { getByText } = render(<Test />);
setTimeout(() => {
expect(getByText('45')).toBeInTheDocument();
}, 15000);
jest.runAllTimers();
});
});
It pass the test, but if we change code line from
expect(getByText('45')).toBeInTheDocument();
to
expect(getByText('55')).toBeInTheDocument();
it passes to... So it seams that it doesn't work as I was expected. Do you have any ideas how to write this test properly? Of course I don't want to delay my tests.