2017-09-25 54 views
2

我正嘗試使用酶對組件進行單元測試淺顯示。試圖測試組件的狀態activeTab,並拋出TypeError: Cannot read property state。我的組件Accordion。 Accordion組件JSX代碼使用酶的反應測試類型錯誤:無法讀取未定義的屬性'狀態'

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 

Accordion.react.test.js

import { shallow } from 'enzyme' 
import Accordion from './components/Accordion' 

test('Accordion component',() => { 
    const component = shallow(<Accordion name={`Main`}/>) 
    expect(component.state('activeTab')).equals(0) 
}) 
+2

測試運行良好,我的電腦上,但我必須要改變'.equals(0)'到'.toEqual(0)'。也許你可以共享更多的調試信息,比如酶/節點版本,或者至少粘貼完整的錯誤信息 - 你粘貼的信息只有信息的一半。 – AVAVT

+0

您是否在Jsx文件中導入REACT? –

+0

是的,我在'jsx'文件中導入了React。 –

回答

0

測試應如何驗證組件的作品,但不是「如何改變的狀態」。您需要將新的道具放入組件並獲得結果,並且預期結果。

我測試過我的部件與快照

這是我的當前項目的一個例子

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

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

這可能是這個範圍界定問題。使用React中的事件處理程序時,必須將構造函數中的事件處理程序綁定到「this」。下面是來自陣營的docs關於它的一些信息:

You have to be careful about the meaning of this in JSX callbacks. In JavaScript, class methods are not bound by default. If you forget to bind this.handleClick and pass it to onClick, this will be undefined when the function is actually called.

This is not React-specific behavior; it is a part of how functions work in JavaScript. Generally, if you refer to a method without() after it, such as onClick={this.handleClick}, you should bind that method.

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> 
     ) 
    } 

} 
+0

請不要使用綁定,如果你想綁定任何東西到任何地方使用箭頭功能。綁定非常慢,你應該知道如果你知道V8是如何工作的。 –

相關問題