So I have a react component that looks something like this:
class SignInForm extends React.Component {
constructor(props) {
super(props);
}
onFormSubmit(event) {
const username = React.findDOMNode(this.refs.username).value;
const password = React.findDOMNode(this.refs.username).value;
// very basic validation
if (username && password.length > 6) {
this.props.flux.signIn({ username, password });
}
event.preventDefault();
}
render() {
return (
<form onSubmit={ this.onFormSubmit.bind(this) } >
<input type="text" ref="username" placeholder="username"/>
<input type="password" ref="password" placeholder="password"/>
<button type="submit">Submit</button>
</form>
);
}
}
And then I want to test it as follows:
describe('The SignInForm', () => {
it('should call `attemptSignIn` when submitted with valid data in its input fields', (done) => {
const spy = sinon.stub(flux.getActions('UserStateActions'), 'attemptSignIn');
const element = <SignInForm { ...componentProps }/>;
const component = TestUtils.renderIntoDocument(element);
const inputs = TestUtils.scryRenderedDOMComponentsWithTag(component, 'input');
TestUtils.Simulate.change(inputs[ 0 ], { target: { value: 'Joshua' } });
TestUtils.Simulate.change(inputs[ 1 ], { target: { value: 'Welcome123' } });
// This works, but I'd rather not set the values using the refs directly
// React.findDOMNode(component.refs.userNameOrEmailAddressInput).value = 'Joshua';
// React.findDOMNode(component.refs.plainTextPasswordInput).value = 'Welcome123';
const DOMNode = React.findDOMNode(component, element);
TestUtils.Simulate.submit(DOMNode);
spy.callCount.should.equal(1);
spy.restore();
});
});
However the values of the references fields on the onFormSubmit
method aren't those set by the Simulate.change
call.
Why not? Is this expected behaviour?
You're missing an
onChange
handler for your input fields which React will then render as uncontrolled inputs.in combination with setting a new state will fix your issues.
React docs explains it here