2017-08-07 15 views
0

LoadingIndicatorテストファイルに以下のコードがあります。私は、LoadIndicatorコンテナクラスをテストするためにJEST + Enzymeを使用しています。JEST + ENZYMEで100%ブランチカバレッジに達することができません

私は支店のカバレッジを100%にするのに苦労しています。それは91%で立ち往生しています。私がカバーすることができないブランチは、LoadIndicatorコンテナクラスの中で(!this.timeoutID)なら、です。私がここで紛失しているものを理解するのを助けてください。

import ...; 

import ConnectedLoadingIndicator,{ LoadingIndicator } from './loadingIndicator'; 

jest.useFakeTimers(); 

describe('LoadingIndicator unconnected container component',() => { 

    let wrapper; 
    let instance; 
    beforeEach(() => { 

        wrapper = shallow(<LoadingIndicator 
             loading='true' 
             error='false' />); 

        instance = wrapper.instance(); 
        }); 

    it('checks loadingIndicator is hidden on loading false',() => { 
    wrapper.setProps({ loading: false, error: false }); 
    expect(instance.state.showIndicator).toBe(false); 
    expect(wrapper.find('.loading-hidden').length).toEqual(1); 
    }); 

    it('checks loadingIndicator is shown after timer runs',() => { 
    wrapper.setProps({ loading: true, error: false }); 
    jest.runOnlyPendingTimers(); 
    expect(instance.state.showIndicator).toBe(true); 
    expect(wrapper.find('.loading-show').length).toEqual(1); 
    }); 

    it('checks loadingIndicator is hidden on error true',() => { 
    wrapper.setProps({ loading: true, error: true }); 
    expect(instance.state.showIndicator).toBe(false); 
    expect(wrapper.find('.loading-hidden').length).toEqual(1); 
    }); 

    it('checks destroyTimer behavior on loading false and error false',() => { 
    wrapper.setProps({ loading: false, error: false }); 
    expect(instance.timeoutID).toBe(null); 
    expect(instance.state.showIndicator).toBe(false); 
    }); 

}); 

LoadingIndicator Containerクラス

import ...; 

import LoadingIndicatorComponent from '../../../../components/loadingIndicator'; 

export class LoadingIndicator extends Component { 

    constructor(props) { 
    super(props); 
    this.timeoutID = null; 
    this.state = { 
     showIndicator: false, 
    }; 
    } 

    componentDidMount() { 
    this.ensureTimer(this.props); 
    } 

    componentWillUnmount() { 
    this.destroyTimer(); 
    } 

    componentWillReceiveProps(props) { 
    if (props.loading !== this.props.loading 
      || props.error !== this.props.error) { 
     this.ensureTimer(props); 
    } 
    } 

    ensureTimer(props) { 
    if (props.loading && !props.error) { 
     if (!this.timeoutID) { 
     this.timeoutID = setTimeout(() => { 
      this.timeoutID = null; 
      this.setState({ showIndicator: true }); 
     }, props.timeoutPeriod); 
     } 
    } else { 
     this.destroyTimer(); 
    } 
    } 

    destroyTimer() { 
    clearTimeout(this.timeoutID); 
    this.timeoutID = null; 
    this.setState({ showIndicator: false }); 
    } 

    render() { 
    console.log(this.state.showIndicator); 
    return (
     <div className = 
     {`${this.state.showIndicator ? 'loading-show' : 'loading-hidden'}`}> 
     <LoadingIndicatorComponent> 
      Loading... 
     </LoadingIndicatorComponent> 
     </div> 
    ); 
    } 

} 

const mapStateToProps = (state) => ({ 
    loading: isLoading(state), 
    error: hasError(state), 
}); 

// timeoutPeriod of 1000 is for showing loading indicator after 1000ms 
LoadingIndicator.defaultProps = { 
    timeoutPeriod: 1000, 
}; 

export default connect(mapStateToProps)(LoadingIndicator); 

答えて

1

私は以下のように私のテストファイルを更新しています。私は、両方のブランチが個別のテストではなく、単一のテストでカバーされなければならないことを発見しました。すでに設定されている場合、カバレッジの問題を解決した場合、timeoutIDのチェックは変更されません。

import React, { Component } from 'react'; 
import { connect } from 'react-redux'; 

import { selectPendingRequest } from './selectors'; 
import LoadingIndicatorComponent from '../../../../components/loadingIndicator'; 
import './loadingIndicator.css'; 

export class LoadingIndicator extends Component { 

    constructor(props) { 
    super(props); 
    this.timeoutID = 0; 
    this.state = { 
     showIndicator: false, 
    }; 
    } 

    componentDidMount() { 
    this.ensureTimer(this.props); 
    } 

    componentWillUnmount() { 
    this.destroyTimer(); 
    } 

    componentWillReceiveProps(props) { 
    if (props.pendingRequest !== this.props.pendingRequest) { 
     this.ensureTimer(props); 
    } 
    } 

    ensureTimer(props) { 
    if (props.pendingRequest > 0) { 
     if (this.timeoutID === 0) { 
     this.timeoutID = setTimeout(() => { 
      this.timeoutID = 0; 
      this.setState({ showIndicator: true }); 
     }, props.timeoutPeriod); 
     } 
    } else { 
     this.destroyTimer(); 
    } 
    } 

    destroyTimer() { 
    clearTimeout(this.timeoutID); 
    this.timeoutID = 0; 
    this.setState({ showIndicator: false }); 
    } 

    render() { 
    return (
     <div className = 
     {`${this.state.showIndicator ? 'loading-show' : 'loading-hidden'}`}> 
     <LoadingIndicatorComponent> 
      Loading... 
     </LoadingIndicatorComponent> 
     </div> 
    ); 
    } 

} 

const mapStateToProps = (state) => ({ 
    pendingRequest: selectPendingRequest(state) //count of pendingRequest 
}); 

LoadingIndicator.defaultProps = { 
    timeoutPeriod: 1000, 
}; 

export default connect(mapStateToProps)(LoadingIndicator); 

import ...; 

import ConnectedLoadingIndicator,{ LoadingIndicator } from './loadingIndicator'; 

jest.useFakeTimers(); 

describe('LoadingIndicator unconnected container component',() => { 

    let wrapper; 
    let spy; 
    let spyEnsureTimer; 
    let instance; 
    let props = { 
    pendingRequest: 0 
    } 
    beforeEach(() => { 
        wrapper = shallow(<LoadingIndicator {...props} />, 
             { lifecycleExperimental: true, }); 

        instance = wrapper.instance(); 
        spy = jest.spyOn(instance, 'componentWillReceiveProps'); 
        spyEnsureTimer = jest.spyOn(instance, 'ensureTimer'); 
        }); 

    it('renders',() => { 
    expect(wrapper.length).toEqual(1); 
    }); 

    it('checks for timeoutID remains unchanged if already set',() => { 
     instance.ensureTimer(props); 
     expect(instance.timeoutID).toBe(0); 
     instance.ensureTimer({ pendingRequest: 1 }); 
     expect(instance.timeoutID).toBe(1); 
     instance.ensureTimer({ pendingRequest: 1 }); 
     expect(instance.timeoutID).toBe(1); 
    }); 

    it('checks componentWillReceiveProps and ensureTimer is called',() => { 
    expect(spy).not.toHaveBeenCalled(); 
    wrapper.setProps({ pendingRequest: 1 }); 
    expect(spy).toHaveBeenCalled(); 
    expect(spyEnsureTimer.mock.calls.length).toBe(1); 
    }); 

    it('checks ensureTimer is not called with same props',() => { 
    expect(spyEnsureTimer.mock.calls.length).toBe(0); 
    wrapper.setProps({ pendingRequest: 0 }); 
    expect(spyEnsureTimer.mock.calls.length).toBe(0); 
    }); 

    it('checks loadingIndicator is shown on pendingRequest more than 0',() => { 
    wrapper.setProps({ pendingRequest: 1 }); 
    jest.runOnlyPendingTimers(); 
    expect(instance.state.showIndicator).toBe(true); 
    expect(wrapper.find('.loading-show').length).toEqual(1); 
    }); 

    it('checks destroyTimer behavior on pendingRequest less than 1',() => { 
    wrapper.setProps({ pendingRequest: 1 }); 
    jest.runOnlyPendingTimers(); 
    expect(instance.state.showIndicator).toBe(true); 
    wrapper.setProps({ pendingRequest: 0 }); 
    expect(instance.timeoutID).toBe(0); 
    expect(instance.state.showIndicator).toBe(false); 
    expect(wrapper.find('.loading-hidden').length).toEqual(1); 
    }); 

}); 

は、私は以下のようにもLoadingIndicatorコンテナクラスを変更しました

関連する問題