2017-09-25 10 views
2

효소 얕은 렌더링을 사용하는 구성 요소에 대한 단위 테스트를 수행하려고합니다. 구성 요소의 state activeTab을 테스트하려고 시도하면 TypeError: Cannot read property state이 발생합니다. 내 구성 요소 아코디언. Accordion 구성 요소 jsx 코드효소를 이용한 반응 테스트 TypeError : 정의되지 않은 '상태'속성을 읽을 수 없음

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

REACT를 Jsx 파일로 가져 왔습니까? –

+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

아무 곳에 나 바인딩하려는 경우 화살표 기능을 사용하려면 bind를 사용하지 마십시오. 바인드가 매우 느리므로 V8의 작동 방식을 알고 있으면 알 수 있습니다. –