Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
38
rated 0 times [  40] [ 2]  / answers: 1 / hits: 17820  / 8 Years ago, fri, december 23, 2016, 12:00:00

I'm having some difficulty testing a component with jest and enzyme. What I would like to do is test submitting the form without a value in the name field. This will make certain that the component is displaying an error. However, when I run the rest I am getting an error in my console:




TypeError: Cannot read property 'value' of undefined




I'm fairly new to front-end testing, and testing in general. So, I'm not entirely sure I'm using enzyme correctly for this type of test. I don't know if my tests are incorrect or if I've just written a component that is not easily tested. I'm open to changing my component if that will make it easier to test?



Component



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,
};


Test



  // 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.');
});

});

More From » reactjs

 Answers
0

As a rule of thumb, you should avoid using refs whenever possible, why? here



In your case, I suggest one of the better approaches could be :



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


I guess this will solve your problem.
With this your test should run fine.


[#59593] Wednesday, December 21, 2016, 8 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
minab

Total Points: 701
Total Questions: 104
Total Answers: 91

Location: Saint Pierre and Miquelon
Member since Fri, Jan 28, 2022
2 Years ago
;