Home Enzyme test for redux form fails when testing form submission
Reply: 1

Enzyme test for redux form fails when testing form submission

Rohini
1#
Rohini Published in 2017-11-03 18:04:26Z

I have a SignUp React component which uses redux form and my onSubmit basically dispatches an async action. I am trying to test my component using Enzyme and Jest by adding a spy to my dispatch and checking if dispatch is invoked on simulating a form submission. However, my test fails.

Here is my SignUp redux form component:

import React from 'react';
import {reduxForm, Field, focus} from 'redux-form';
import Input from './input';
import {required, nonEmpty, email, isTrimmed, length} from '../validators';
import {registerUser} from '../actions/users';
import {login} from '../actions/auth';
export class SignUpForm extends React.Component {
    onSubmit(values) {
        const {username, password, fname, lname} = values;
        const newUser = {
            username, 
            password, 
            user: {
               firstName: fname, 
               lastName: lname
            }
        };
        return this.props
            .dispatch(registerUser(newUser))
            .then(() => this.props.dispatch(login(username, password)));
    }

    render() {
        let errorMessage;
        if (this.props.error) {
            errorMessage = (
                <div className="message message-error">{this.props.error </div>
            );
        }

        return (
                <form className='signup-form' onSubmit={this.props.handleSubmit(values =>
                this.onSubmit(values)
            )}>

                    {errorMessage}
                    <Field
                    name="fname"
                    type="text"
                    component={Input}
                    label="First Name"
                    validate={[required, nonEmpty]}
                    />
                    <Field
                    name="lname"
                    type="text"
                    component={Input}
                    label="Last Name"
                    validate={[required, nonEmpty]}
                    />
                    <Field
                    name="username"
                    type="email"
                    component={Input}
                    label="Email"
                    validate={[required, nonEmpty, email, isTrimmed]}
                    />
                    <Field
                    name="password"
                    type="password"
                    component={Input}
                    label="Password"
                    validate={[required, nonEmpty, length({min: 10, max: 72})]}
                    />
                    <button
                    type="submit"
                    disabled={this.props.pristine || this.props.submitting}>
                    Sign Up
                    </button>
                </form>                             
        );
    }
}
export default reduxForm({
    form: 'signup',
    onSubmitFail: (errors, dispatch) => 
        dispatch(focus('signup', Object.keys(errors)[0]))
})(SignUpForm);

Here is my test:

import React from 'react';
import {shallow, mount} from 'enzyme';
import SignUpForm from './signup';
import {registerUser} from '../actions/users';
import { reducer as formReducer } from 'redux-form'
import { createStore, combineReducers, applyMiddleware } from 'redux'
import { Provider } from 'react-redux'
import thunk from 'redux-thunk';
import {stockReducer} from '../reducers';
describe('<SignUpForm />', () => {
    let store
    let wrapper
    let dispatch
    beforeEach(() => {
        store = createStore(combineReducers({ form: formReducer, stock: stockReducer }),applyMiddleware(thunk))
        dispatch = jest.fn()
        wrapper = mount(
            <Provider store={store}>
                <SignUpForm dispatch={dispatch}/>
            </Provider>
        );
    })

    it('should fire onSubmit callback when form is submitted', (done) => {
        const form = wrapper.find('form');
        form.find('#fname').simulate('change', {target: {value: 'fname'}});
        form.find('#lname').simulate('change', {target: {value: 'lname'}});
        form.find('#username').simulate('change', {target: {value: 'fname@email.com'}});
        form.find('#password').simulate('change', {target: {value: 'password1234'}});
        form.simulate('submit');
        expect(dispatch).toHaveBeenCalled();
    });
});

My test fails with the following error: expect(jest.fn()).toHaveBeenCalled() Expected mock function to have been called.

Please help me understand what is going wrong.

Swapnil
2#
Swapnil Reply to 2018-01-12 05:17:13Z

The problem here is that you are not awaiting anywhere in your test on the promise returned by your onSubmit function so your assert is getting executed before your promise resolves.
I will suggest you to properly refactor your code to make it "testable". You can take a look at following link on how to test async calls using jest: https://facebook.github.io/jest/docs/en/asynchronous.html
I will also suggest you to use redux-thunk which will make your life easier.

You need to login account before you can post.

About| Privacy statement| Terms of Service| Advertising| Contact us| Help| Sitemap|
Processed in 0.31466 second(s) , Gzip On .

© 2016 Powered by mzan.com design MATCHINFO