2017-04-21 106 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幫我找到這個解決方案。