2016-12-23 2 views
1

jest와 효소가있는 구성 요소를 테스트하는 데 어려움이 있습니다. 내가하고 싶은 것은 이름 필드에 값없이 폼을 테스트하는 것입니다. 그러면 구성 요소에 오류가 표시됩니다. 그러나 나머지를 실행할 때 내 콘솔에 오류가 발생합니다.효소 시뮬레이션 양식 제출, 정의되지 않은 'value'속성을 읽을 수 없음

TypeError: Cannot read property 'value' of undefined

저는 프론트 엔드 테스트 및 테스트 전반에서 상당히 새로운 기술입니다. 그래서 저는 이러한 유형의 시험을 위해 효소를 정확하게 사용하고 있는지 확신 할 수 없습니다. 내 테스트가 잘못되었거나 쉽게 테스트되지 않은 구성 요소를 작성한 것인지 여부는 알 수 없습니다. 그게 더 쉽게 테스트 할 수 있도록 내 구성 요소를 변경하려면 열려 있습니까?

부품

// all other code omitted 
    // bear in mind I am shallow rendering the component 

    describe('the user does not populate the input field',() => { 

    it('should display an error',() => { 
     const form = wrapper.find('form').first(); 
     form.simulate('submit', { 
     preventDefault:() => { 
     }, 
     // below I am trying to set the value of the name field 
     target: [ 
      { 
      value: '', 
      } 
     ], 
     }); 
     expect(
     wrapper.text() 
    ).toBe('Please enter your name.'); 
    }); 

    }); 

답변

1

가능한 한 항상 refs를 사용하지 않는 것이 좋습니다. 그 이유는 무엇입니까? 귀하의 경우에는 here

, 내가 더 좋은 방법 중 하나가 될 수 있습니다 제안 :

class InputForm extends Component { 
     constructor(props) { 
     super(props); 
     this.state = { 
      name : '' 
     } 
     this.onFormSubmit = this.onFormSubmit.bind(this); 
     this.handleNameChange = this.handleNameChange.bind(this); 
     } 


     handleNameChange(e){ 
     this.setState({name:e.target.value}) 
     } 

     onFormSubmit(e) { 
     e.preventDefault(); 
     this.props.submitForm(this.state.name); 
     } 

     render() { 
     let errorMsg = (this.props.validationError ? 'Please enter your name.' : null); 
     return (
      <form onSubmit={(e) => this.onFormSubmit(e)}> 
      <input 
       type="text" 
       placeholder="Name" 
       onChange={this.handleNameChange} 
      /> 
      <p className="error"> 
       {errorMsg} 
      </p> 
      <input 
       type="submit" 
       className="btn" 
       value="Submit" 
      /> 
      </form> 
     ); 
     } 
    } 

나는이 문제를 해결할 것 같아요. 이 테스트는 정상적으로 실행되어야합니다.

+0

귀하의 의견에 감사드립니다. 그러나 두 개의 개별 구성 요소로 상태를 관리하고 싶지는 않습니다. ''inputForm''' 클래스는 훨씬 더 큰 어플리케이션의 자식 컴포넌트입니다. 모든 상태 관리는 부모 구성 요소에 의해 처리되고 필요한 경우 소품으로 전달됩니다. 시간이 지나면 더 나은 상태 관리를 위해 Redux를 사용하도록 애플리케이션을 업데이트 할 것입니다. –

1

문제 this thread 이미 논의 된

class InputForm extends Component { 
    constructor(props) { 
    super(props); 
    this.onFormSubmit = this.onFormSubmit.bind(this); 
    } 

    onFormSubmit(e) { 
    e.preventDefault(); 
    // this is where the error comes from 
    const name = this.name.value; 
    this.props.submitForm(name); 
    } 

    render() { 
    let errorMsg = (this.props.validationError ? 'Please enter your name.' : null); 
    return (
     <form onSubmit={(e) => this.onFormSubmit(e)}> 
     <input 
      type="text" 
      placeholder="Name" 
      ref={ref => { 
       this.name = ref 
       }} 
     /> 
     <p className="error"> 
      {errorMsg} 
     </p> 
     <input 
      type="submit" 
      className="btn" 
      value="Submit" 
     /> 
     </form> 
    ); 
    } 
} 
InputForm.propTypes = { 
    submitForm: React.PropTypes.func.isRequired, 
}; 

시험.
그리고이 솔루션은 나를 위해 작동합니다.

import { mount, shallow } from 'enzyme'; 
    import InputForm from '../InputForm': 
    import React from 'react'; 
    import { spy } from 'sinon'; 

    describe('Form',() => { 
    it('submit event when click submit',() => { 
     const callback = spy(); 
     const wrapper = mount(<InputForm />); 
     wrapper.find('[type="submit"]').get(0).click(); 
     expect(callback).to.have.been.called(); 
    }); 
    }); 

jest 대신 mocha + chai를 사용합니다. 그러나 당신은 그것을하는 방법에 대한 아이디어를 얻을 수 있습니다.

+0

이 정보는 유용하지만 사용자가 질문을 잘못 이해했다고 생각합니다. 예, 양식 제출을 테스트하고 싶지만 값으로 다시 테스트하고 값없이 다시 테스트하려고합니다. –

2

제출 이벤트를 시뮬레이트하기 위해 이벤트 객체를 전달할 필요가 없다고 생각합니다. 이것은 효과가있다.

describe('the user does not populate the input field',() => { 

    it('should display an error',() => { 
     const form = wrapper.find('form').first(); 
     form.simulate('submit'); 
     expect(
     wrapper.find('p.error').first().text() 
    ).toBe('Please enter your name.'); 
    }); 

    }); 
+1

나는 이벤트 객체를 전달해야한다고 믿는다. 그렇지 않으면 에러가 발생한다. TypeError : undefined'''의 'preventDefault'속성을 읽을 수 없다. http://airbnb.io/enzyme/docs/api/ShallowWrapper/simulate.html 효소 시뮬레이션이 양식을 제출할 때''onFormSubmit''' 메소드를 호출합니다. 그러면'''preventDefault''' 이벤트 객체가 호출됩니다 방법. 빈''preventDefault''' 메쏘드를 전달하지 않으면 테스트가 에러를 발생시킵니다. 더 이해하기 위해서''inputForm''' 클래스를 검사하십시오. –