使用酶进行反应测试TypeError:无法读取属性' state'未定义的

时间:2017-09-25 10:24:33

标签: javascript reactjs enzyme jest

我尝试使用酶浅层渲染对组件进行单元测试。尝试测试组件的状态activeTab并抛出const actions = { getCharts( { commit, rootState } ) { // Load data from server return api.get( rootState.Laravel.api_url + '/chart' ) .then( ( response ) => { // Store the returned data commit( 'STORE_CHART', response.data.data ); }) .catch( ( error ) => console.log( error ) ); } } const mutations = { STORE_CHART( state, charts ) { _.forEach( charts, function( chart ) { Vue.set( state.charts, chart.id, Object.freeze( chart ) ); }); } } 。我的组件手风琴。 Accordion组件jsx代码

TypeError: Cannot read property state

Accordion.react.test.js

 class Accordion extends Component {
    constructor(props) {
        super(props)
        this.state = {
            activeTab: 0
        }
    }

    static defaultProps = {
        tabs: [{title: 'Status'}, {title: 'Movement'}]
    }

    render() {
        const { tabs } = this.props
            , { activeTab } = this.state
        return (
            <div className={`accordion`}>
                {tabs.map((t, i) => {
                    const activeClass = activeTab === i ? `accordion--tab__active` : ''
                    return(
                        <section key={i} className={`accordion--tab ${activeClass}`}>
                            <header className={`accordion--header`}>
                                <h4 className={`accordion--title`}>
                                    <button onClick={() => {this._selectAccordion(i)}}>{t.title}</button>
                                </h4>
                            </header>
                            <div className="accordion--content">
                                {t.title}
                                Content
                            </div>
                        </section>
                    )
                })}
            </div>
        )
    }
    _selectAccordion = activeTab => {this.setState({activeTab})}
}

export default Accordion

2 个答案:

答案 0 :(得分:2)

这可能是一个范围问题。使用React中的事件处理程序,您必须将构造函数中的事件处理程序绑定到&#34; this&#34;。以下是React的docs关于它的一些信息:

  

在JSX回调中你必须要小心这个含义。在   JavaScript,类方法默认不受约束。如果你忘记了   绑定this.handleClick并将其传递给onClick,这将是未定义的   当实际调用该函数时。

     

这不是特定于React的行为;它是功能的一部分   在JavaScript中工作。通常,如果你引用一个没有()的方法   在它之后,例如onClick = {this.handleClick},你应该绑定它   方法

class Accordion extends Component {
    constructor(props) {
        super(props)
        this.state = {
            activeTab: 0
        }

        // This binding is necessary to make `this` work in the callback
        this._selectAccordion = this._selectAccordion.bind(this);
    }

    static defaultProps = {
        tabs: [{title: 'Status'}, {title: 'Movement'}]
    }

        _selectAccordion(activeTab){
            this.setState({activeTab : activeTab})
        }

    render() {
        const { tabs } = this.props,
        { activeTab } = this.state
        return (
            <div className={`accordion`}>
                {tabs.map((t, i) => {
                    const activeClass = activeTab === i ? `accordion--tab__active` : ''
                    return(
                        <section key={i} className={`accordion--tab ${activeClass}`}>
                            <header className={`accordion--header`}>
                                <h4 className={`accordion--title`}>
                                    <button onClick={() => {this._selectAccordion(i)}}>{t.title}</button>
                                </h4>
                            </header>
                            <div className="accordion--content">
                                {t.title}
                                Content
                            </div>
                        </section>
                    )
                })}
            </div>
        )
    }

}

答案 1 :(得分:0)

您的测试应该验证组件的工作方式,而不是“如何更改状态”。你需要在组件中添加新的道具并获得结果,结果是预期的。

我用快照测试了我的组件

这是我当前项目的一个例子

describe('<Component />', () => {
  it('Page rendered', () => {
    const rendered = renderComponent({
      ...testProps,
      loadDataList,
      loading: true,
    });

    expect(rendered).toMatchSnapshot();
  });
});