2017-04-21 66 views
0

我很难测试用REDX形式装饰的反应组件。以下是我试图运行的一些集成测试。他们都失败了,所以很明显我没有正确设置测试。在这里和GitHub上似乎有很多讨论关于用redux-form进行单元和集成测试的难度。任何帮助,将不胜感激。无法测试REDX形式

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._%+-][email protected][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; 

confirmation_test.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: '[email protected]' } }); 
     form.simulate('submit'); 
     expect(sendActivationEmail.callCount).to.equal(1); 
     done(); 
    }); 

    it('calls resetAuthError on unmount', (done) => { 
     subject.unmount(); 
     expect(resetAuthError.calledOnce).to.equal(true); 
    }); 
    }); 

回答

0

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

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

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

2009年,由于this thread @tylercollier帮我找到这个解决方案。