2017-05-11 8 views
0

나는 테스트 용으로 테이프, 효소, jsdom 및 sinon을 사용하고있다. 메소드를 호출 한 후에 상태가 변경되었다는 간단한 것을 테스트하고 싶습니다.Test React 컴포넌트 메소드와 setInterval

class Countdown extends Component { 
     state = { 
     count: 0, 
     countdownStatus: 'stopped' 
     } 

     componentDidUpdate = (prevProps, prevState) => { 
     if (this.state.countdownStatus !== prevState.countdownStatus) { 
     switch (this.state.countdownStatus) { 
      case 'started': 
      this.startTimer() 
      break 
      } 
     } 
     } 

    startTimer =() => { 
     this.timer = setInterval(() => { 
      const newCount = this.state.count - 1 
      this.setState({ 
      count: newCount >= 0 ? newCount : 0 
      }) 
     }, 1000) 
     } 

     handleSetCountdown = (seconds) => { 
     this.setState({ 
      count: seconds, 
      countdownStatus: 'started' 
     }) 
     } 

     render() { 
     const {count} = this.state 
     return (
      <div> 
      <Clock totalSeconds={count} /> 
      <CountdownForm onSetCountdown={this.handleSetCountdown} /> 
      </div> 
     ) 
     } 
    } 

    export default Countdown 

그리고 이것은 작동하지 않습니다. 그것은 통과하지만, 마지막 시험은 항상 어떤 이유에서 건 멈추지 만 모든 시험은 통과하지만 끝내지는 않습니다. 어쩌면 그것은 테스트하지는 않지만 setInterval 때문일 수도 있습니다.

test('Countdown => should set state to 10, (t) => { 
    t.plan(1) 
    const wrapper = shallow(<Countdown />) 
    wrapper.instance().handleSetCountdown(10) 
    wrapper.update() 
    t.equal(wrapper.state().count, 10) 
}) 

편집 : 좋아, 내가 그것을 아래로 생각. 테스트는 setInterval 때문에 종료되지 않습니다. 어떻게 해결할 수 있을까요?

편집 2 : 해결책은 매우 간단했습니다. 방금 추가 한

var clock = sinon.useFakeTimers() 

등 모든 테스트가 완료되어야합니다.

+1

을 완료 할 수 있도록 Sinon 원인 sinonjs.org/releases/v2.2.0/fake-timers sinon 가짜 타이머를 사용하면 전 세계의 setTimeout을 대체하는 .org/releases/v2.2.0/가짜 타이머/ –

+0

감사합니다. Patrick. 그것은 작동합니다. 방금 var clock = sinon.useFakeTimers()를 추가하고 모든 테스트를 끝내야합니다. 의견을 적어서 답변을 해결책으로 수락 할 수 없습니다. 다른 사람들이 볼 수 있도록 내 질문을 업데이트 할 것입니다. –

+0

도와 드리겠습니다. 문서를 만들 때 이상적이 될 수있는 코드를 사용하여 직접 답변을 작성할 수 있습니다 (그리고 ☺ bad에 대한 배지도 얻을 수 있습니다) –

답변

0

이 문제에 대한 답변은 간단합니다. HTTP : // sinonjs 테스트 당신은 (그리고해야) Sinon의 가짜 타이머를 사용할 수 있습니다

test('Countdown => should set state to 10', (t: Object) => { 
    t.plan(1) 
    const wrapper: Object = shallow(<Countdown />) 
    /* Causes Sinon to replace the global setTimeout so tests can finish */ 
    const clock = sinon.useFakeTimers() 
    const instance = wrapper.instance() 
    instance.handleSetCountdown(10) 
    t.equal(wrapper.state().count, 10) 
})