vendredi 30 novembre 2018

Testing React Redux - cannot read properties from store, or wrapper undefined

Im having a bit of a problem setting up a Redux store in my component for my test suite. The problem is that even if I try a unconnected mount then the test throws errors looking for variables in authState. I have the following component:

import React, { Component } from 'react';
import { Link, Redirect } from "react-router-dom";
import {bindActionCreators} from 'redux';
import {connect} from 'react-redux';
import * as authActions from '../../../actions/auth.actions';

export class PasswordReset extends Component {
    constructor(props) {
        super(props);
        this.state = {
            email: '',
            emailConfirm: '',
            message: ""
        };
    }

    handleChange = e => {
        e.preventDefault();
        const { value, name } = e.target;

        if (name === 'email') {
            this.setState({...this.state, email: value.trim()});
        } else if (name === 'secondary') {
            this.setState({...this.state, emailConfirm: value.trim()});
        }
    }

    handleSubmit = e => {
        e.preventDefault();
        if (this.state.email.length === 0 && this.state.emailConfirm.length === 0) {
            this.setState({message: "Please Enter and Confirm Email Before Submit"});
            return;
        }

        if (this.state.email !== this.state.emailConfirm) {
            this.setState({message: 'Emails Do Not Match, Please Try Again'});
            return;
        }

        this.props.authActions.resetPassword(this.state.email);
    }

    render() {
        if (this.props.authState.resetStatus === 'reset') {
            return <Redirect to='/login' />
        }
        const error = this.props.authState.resetError === 'TypeError: Failed to fetch' ? 'Agent Id does not exist' : false
        return (
            <div className={'container-login100'}>
                <div className={'wrap-login100 p-t-85 p-b-20'}>
                    <form className={'login100-form validate-form'}>
                        <span className={'login100-form-title p-b-70'}>Reset Password</span>
                        <div className={'wrap-input100 validate-input m-t-85 m-b-35'}>
                        <div style=>
                        {error || this.state.message}
                        </div>
                            <input
                                onChange={e => this.handleChange(e)}
                                className={'input100'}
                                name='email'
                                value={this.state.email}
                                placeholder="Please Enter Your Email"
                                required
                            />
                        </div>
                        <div className={'wrap-input100 validate-input m-t-85 m-b-35'}>
                            <input
                                onChange={e => this.handleChange(e)}
                                className={'input100'}
                                name="secondary"
                                value={this.state.secondary}
                                placeholder="Please Confirm By Re-entering Your Email"
                                required
                            />
                        </div>
                        <div className={'container-login100-form-btn'}>
                            <button className={'login100-form-btn btn-disabled'} onClick={e => this.handleSubmit(e)}>Reset Password</button>
                        </div>
                        <div className={'container-login100-form-btn'}>
                            <Link to='/login'>Back to Login</Link>
                        </div>
                    </form>
                </div>
            </div>
        )
    }
}

const mapStateToProps = state => ({
    authState: state.auth,
})

const mapDispatchToProps = dispatch => ({
    authActions: bindActionCreators({resetPassword: authActions.resetPassword}, dispatch),
})

export default connect(mapStateToProps, mapDispatchToProps)(PasswordReset);

And the following test structure:

import React from 'react';
import configureStore from 'redux-mock-store';
import Enzyme, {mount, shallow} from 'enzyme';
import Provider from 'react-redux';
import Adapter from 'enzyme-adapter-react-16';

import ConnectedPasswordReset, {PasswordReset} from '../';

Enzyme.configure({adapter: new Adapter()});

const mockStore = configureStore();
let wrapper, store, mWrapper;
const initialState = {isLoggedIn: false, isInProgress: false, email: null, error: null, resetError: null, resetStatus: null};

describe('PasswordReset component', () => {
    beforeEach(() => {
        store = mockStore(initialState);
        wrapper = shallow(<PasswordReset store={store} />);
        mWrapper = mount(<Provider store={store}><ConnectedPasswordReset /></Provider>);
    })

    it('shallow - should have initial state.email of ""', () => {
        expect(wrapper.state().email).toEqual('');
    });

    it('mount - should have a initial state.email of ""', () => {
        expect(mWrapper.state().email).toEqual('');
    });
});

Im getting the following output:

testing output

Aucun commentaire:

Enregistrer un commentaire