2

I have a react form which sends a request to backend when the form is submitted:

import React, {Component} from 'react';
import request from 'superagent';

export default class RegisterForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      username: '',
      password: ''
    }
  }

  render() {
    return <form id="form" onSubmit={this._onSubmit.bind(this)}>
      <div>
        <h1>Register</h1>
      </div>
      <div>
        <input id="username" type="text" placeholder="username" onChange={event => {
          this.setState({username: event.target.value})
        }}/>
      </div>
      <div>
        <input id="password" type="password" placeholder="password" onChange={event => {
          this.setState({password: event.target.value})
        }}/>
      </div>
      <div>
        <button type="submit">Register</button>
      </div>
    </form>
  }

  _onSubmit(event) {
    event.preventDefault();

    request
      .post('/api/users')
      .send({
        username: this.state.username,
        password: this.state.password
      })
      .end((err, res) => {
        if (err) {
          console.error(err);
          if (res.statusCode === 400) {
            return window.alert('invalid data:' + res.text);
          }
          if (res.statusCode === 409) {
            return window.alert('registering failed' + res.text);
          }
          return window.alert('unknown err:' + res.statusCode);
        }
        window.alert('registering successfully: ' + res.text);
      })
  }

}

In the test, I simulate the form submit and check if the handling of response http code correctly:

import nock from 'nock';
import RegisterForm from '../../public/register-form.jsx';
import {shallow, mount} from 'enzyme';
import React from 'react';
import jsdomGlobal from 'jsdom-global';
jsdomGlobal();

it('register successfully', (done) => {
  nock(/.*/)
    .post('/api/users', {
      username: 'freewind',
      password: '123456'
    })
    .reply(201, "ok");

  spyOn(window, 'alert');
  const wrapper = mount(<RegisterForm />);

  wrapper.find('#username').simulate('change', {target: {value: 'freewind'}});
  wrapper.find('#password').simulate('change', {target: {value: '123456'}});
  wrapper.find('#form').simulate('submit');

  setTimeout(() => {
    expect(window.alert).toHaveBeenCalledWith('registering successfully: ok');
    done();
  }, 100);
});

You can see I have to wait for 100ms before checking window.alert.

Is there any better way to do it?

This is a project you can clone and run on your computer: https://github.com/js-demos/express-react-register-test-demo

Freewind
  • 193,756
  • 157
  • 432
  • 708

0 Answers0