Testing React form components

javascript, jestjs, reactjs

Solution

React TestUtils allows you to simulate form submission:

var addForm = TestUtils.renderIntoDocument(AddForm(null));
var form = TestUtils.findRenderedDOMComponentWithTag(addForm, 'form');
TestUtils.Simulate.submit(form);

The way I would test the actions is by manually mocking out `addTeam`. Before simulating anything in the test, do something like:

var TeamActions = require('../actions/team_actions');
TeamActions.addTeam = jest.genMockFn();
/* then simulate submission... */
expect(TeamActions.addTeam).toBeCalledWith({name: 'name', rating: 'rating'});

For testing the input values, just use the refs.

addForm.refs.name.getDOMNode().value = 'Some Name';
/* perform some action that should clear input */
expect(addForm.refs.name.getDOMNode().value).toEqual('');

edit

To answer your edited question, it looks like you actually don't need to manually mock `addTeam`; I just tried it out and it seems like Jest figured out how to mock the McFly actions.

Problem

In my tutorial-like application I have a AddForm component: ``` var React = require('react'); var Input = require('react-bootstrap').Input; var TeamActions = require('../actions/team_actions.js'); var AddForm = React.createClass({ handleFormSubmit: function(e) { e.preventDefault(); var name = this._trimmedValue(this.refs.name); var rating = this._trimmedValue(this.refs.rating); if (name && rating) { TeamActions.addTeam( {name: name, rating: rating} ); this._clearField(this.refs.name); this._clearField(this.refs.rating); } }, _trimmedValue: function(field) { return field.getInputDOMNode().value.trim(); }, _clearField: function(field) { field.getInputDOMNode().value = ''; }, render: function() { return ( <form onSubmit={this.handleFormSubmit}> <Input label="Name" type="text" placeholder="Name" ref="name" /> <Input label="Rating" type="text" placeholder="Rating" ref="rating" /> <Input bsStyle="primary" type="submit" value="Add!" /> </form> ); } }) module.exports = AddForm; ``` TeamActions: ``` var McFly = require('mcfly'); var Flux = new McFly(); var TeamConstants = require('../constants/team_constants.js'); var TeamActions = Flux.createActions({ addTeam: function(team) { return { actionType: TeamConstants.ADD_TEAM, team: team } } }); module.exports = TeamActions; ``` As you can see, I'm using McFly and React-Bootstrap here. Now I want to test it, using jest. I would like to have following test cases: 1) if someone tries to submit a form with empty inputs, nothing should happen (to be more specific - there should be no interaction on TeamActions mock) 2) if one submits a form with valid name and rating, then there should be a proper call to TeamActions mock 3) if one submits a form with valid name and rating, then name and rating inputs should be cleaned. How do I test it? Should I access the DOM somehow, using react's TestUtils? Should I somehow simulate form submission? If so, how do I do that? And last thing - my AddForm depends on TeamActions. By writing: ``` jest.dontMock('../add_form.js'); ``` is jest instructed to mock all those dependencies (react, react-bootstrap, team_actions) or should I somehow mock TeamActions myself? // edit: Because someone said I asked too much quuestions in one topic, to be more specific: How can I simulate a form submission with specific payload, using TestUtils? Do I need to mock TeamActions myself or is is mocked for me automatically?

Original source