我是否必须使用`setTimeout`来测试测试中反应组件的异步代码?

时间:2016-08-23 14:39:00

标签: asynchronous reactjs jasmine superagent nock

我有一个反应表单,在提交表单时向后端发送请求:

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

}

在测试中,我模拟表单提交并检查响应http代码的处理是否正确:

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

您可以在检查100ms之前看到我必须等待window.alert

有没有更好的方法呢?

这是一个可以在您的计算机上克隆并运行的项目:https://github.com/js-demos/express-react-register-test-demo

0 个答案:

没有答案