Javascript 无法测试redux表单

Javascript 无法测试redux表单,javascript,reactjs,redux,redux-form,enzyme,Javascript,Reactjs,Redux,Redux Form,Enzyme,我在测试用redux表单装饰的react组件时遇到困难。下面是我正在尝试运行的一些集成测试。他们都失败了,所以很明显我没有正确设置测试。关于使用redux表单进行单元和集成测试的挑战性,这里和GitHub上似乎有很多讨论。任何帮助都将不胜感激 confirmation.js import React, { Component } from 'react'; import { reduxForm, Field } from 'redux-form'; import { connect } from

我在测试用redux表单装饰的react组件时遇到困难。下面是我正在尝试运行的一些集成测试。他们都失败了,所以很明显我没有正确设置测试。关于使用redux表单进行单元和集成测试的挑战性,这里和GitHub上似乎有很多讨论。任何帮助都将不胜感激

confirmation.js

import React, { Component } from 'react';
import { reduxForm, Field } from 'redux-form';
import { connect } from 'react-redux';
import { sendActivationEmail, resetAuthError } from '../../actions';

export const renderField = ({ input, label, type, meta: { touched, error } }) => (
  <fieldset className="form-group">
    <div className={touched && error ? 'has-danger' : ''}>
      <p>Resend Confirmation Instructions</p>
      <input {...input} placeholder={label} type={type} className="form-control"/>
      {touched && error && <span className="error">{error}</span>}
    </div>
  </fieldset>
)

export class Confirmation extends Component {
  componentWillUnmount() {
    this.props.resetAuthError();
  }

  handleFormSubmit({ email }) {
    this.props.sendActivationEmail({ email });
  }

  renderAlert() {
    if (this.props.errorMessage) {
      return (
        <div className="alert alert-danger">
          <strong>Oops!</strong> {this.props.errorMessage}
        </div>
      )
    }
  }

  render() {
    const { handleSubmit } = this.props;
    return (
      <div>
        {this.renderAlert()}
        <form onSubmit={handleSubmit(this.handleFormSubmit.bind(this))}>
          <Field
            label="Email"
            name="email"
            component={renderField}
            type="text"
          />
          <button type="submit" className="btn btn-primary">Resend</button>
        </form>
      </div>
    );
  }
}

 function validate(formProps) {
  const errors = {};

  if (!formProps.email) {
    errors.email = 'Please enter an email';
  } else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(formProps.email)) {
    errors.email = 'Please enter a valid email address';
  }

  return errors;
}

function mapStateToProps(state) {
  return { errorMessage: state.auth.error }
}

Confirmation = reduxForm({
  form: 'confirmation',
  validate
})(Confirmation);

Confirmation = connect(mapStateToProps, { sendActivationEmail, resetAuthError 
})(Confirmation);

export default Confirmation;
import React,{Component}来自'React';
从'redux form'导入{reduxForm,Field};
从'react redux'导入{connect};
从“../../actions”导入{sendActivationEmail,resetAuthError};
export const renderField=({input,label,type,meta:{toucted,error}})=>(
重新发送确认指令

{触摸&&error&&{error} ) 导出类确认扩展组件{ 组件将卸载(){ this.props.resetAuthError(); } handleFormSubmit({email}){ this.props.sendActivationEmail({email}); } renderAlert(){ 如果(此.props.errorMessage){ 返回( 哎呀!{this.props.errorMessage} ) } } render(){ const{handleSubmit}=this.props; 返回( {this.renderAlert()} 重发 ); } } 函数验证(formProps){ 常量错误={}; 如果(!formProps.email){ errors.email='请输入电子邮件'; }否则,如果(!/^[A-Z0-9.%+-]+@[A-Z0-9.-]+\[A-Z]{2,4}$/i.test(formProps.email)){ errors.email='请输入有效的电子邮件地址'; } 返回错误; } 函数MapStateTops(状态){ 返回{errorMessage:state.auth.error} } 确认=reduxForm({ 表格:‘确认书’, 验证 })(确认); 确认=连接(MapStateTops,{sendActivationEmail,resetAuthError })(确认); 导出默认确认;
确认测试.js

import React from 'react';
import { expect } from 'chai';
import { shallow, mount, unmount } from 'enzyme';
import sinon from 'sinon';

import { Provider } from 'react-redux';
import { createStore, applyMiddleware } from 'redux';
import reduxThunk from 'redux-thunk';

import reducers from '../../../src/reducers';
import ConfirmationContainer, { ConfirmationComponent, renderField }  from '../../../src/components/auth/confirmation';

const createStoreWithMiddleware = applyMiddleware(reduxThunk)(createStore);
const store = createStoreWithMiddleware(reducers);

  describe('Container', () => {
    let sendActivationEmail, resetAuthError, props, errorMessage, subject;
    beforeEach(() => {
      sendActivationEmail = sinon.spy();
      resetAuthError = sinon.spy();
      props = {
        sendActivationEmail,
        resetAuthError,
        errorMessage: 'required'
      };

      subject = mount(
        <Provider store={store}>
          <ConfirmationContainer {...props} />
        </Provider>
        )
      });

    it('renders error message', (done) => {
      expect(subject.find('.alert')).to.have.length(1);
      done();
    });

    it('calls sendActivationEmail on submit', (done)=> {
        const form = subject.find('form');
        const input = subject.find('input').first();

        input.simulate('change', { target: { value: 'test@gmail.com' } });
        form.simulate('submit');
        expect(sendActivationEmail.callCount).to.equal(1);
        done();
    });

    it('calls resetAuthError on unmount', (done) => {
        subject.unmount();
        expect(resetAuthError.calledOnce).to.equal(true);
    });
  });
从“React”导入React;
从“chai”导入{expect};
从“酶”导入{shall,mount,unmount};
从“sinon”进口sinon;
从'react redux'导入{Provider};
从“redux”导入{createStore,applyMiddleware};
从“redux thunk”导入redux thunk;
从“../../../src/reducers”导入减速机;
从“../../../src/components/auth/confirmation”导入确认容器,{ConfirmationComponent,renderField};
const createStoreWithMiddleware=applyMiddleware(reduxThunk)(createStore);
const store=createStoreWithMiddleware(reducers);
描述('容器',()=>{
让sendActivationEmail、resetAuthError、props、errorMessage、subject;
在每个之前(()=>{
sendActivationEmail=sinon.spy();
resetAuthError=sinon.spy();
道具={
发送激活邮件,
重置错误,
errorMessage:'必需'
};
主题=坐骑(
)
});
它('呈现错误消息',(完成)=>{
expect(subject.find('.alert')).to.have.length(1);
完成();
});
它('提交时调用sendActivationEmail',(完成)=>{
const form=subject.find('form');
const input=subject.find('input').first();
input.simulate('change',{target:{value:'test@gmail.com' } });
形式。模拟(“提交”);
expect(sendActivationEmail.callCount).to.equal(1);
完成();
});
它('卸载时调用resetAuthError',(完成)=>{
subject.unmount();
expect(resetAuthError.calledOnce).to.equal(true);
});
});

添加
mergeProps
作为
connect()
函数的第三个参数使我的前两个测试通过。对于第三个测试,我在测试结束时添加了
done()
,我最初忽略了添加。以下是我添加到容器组件以使测试通过的代码:

const mergeProps = (stateProps, dispatchProps, ownProps) =>
    Object.assign({}, stateProps, dispatchProps, ownProps)

Confirmation = connect(mapStateToProps, { sendActivationEmail, resetAuthError 
}, mergeProps)(Confirmation);
感谢@tylercollier on帮助我找到此解决方案