Testing method inside functional component in React using Jest / Enzyme

Viewed 3284

Following is my React Functional Component which I am trying to test using jest / enzyme.

React Functional Component Code -

export const UserForm = props => {
    const {labels, formFields, errorMessages} = props;
    const [showModal, setShowModal] = React.useState(false);
    const [newId, setNewId] = React.useState('');

    const showModal = () => {
        setShowModal(true);
    }

    const closeModal = () => {
        setShowModal(false);
    };

    const handleSubmit = data => {
        Post(url, data)
            .then(resp => {
                const userData = resp.data;
                setNewId(() => userData.id);
                showModal();
            })
    }

    return (
        <div className="user-form">
            <UserForm
                fields={formFields}
                handleSubmit={handleSubmit}
                labels={labels}
                errors={errorMessages}
            />
            {showModal && <Modal closeModal={closeModal}>
                <div className="">
                    <h3>Your new id is - {newId}</h3>
                    <Button
                        type="button"
                        buttonLabel="Close"
                        handleClick={closeModal}
                        classes="btn btn-close"
                    />
                </div>
            </Modal>}
        </div>
    )
};

Now I am trying to test showModal, closeModal and handleSubmit method, but my tests are failing. Let me know the correct way of testing React Hooks and methods inside functional component.

My test case -

import React from 'react';
import { UserForm } from '../index';
import { shallow } from 'enzyme';

describe('<UserForm />', () => {
    let wrapper;
    const labels = {
        success: 'Success Message'
    };
    const formFields = [];
    const errorMessages = {
        labels: {
            firstName: 'First Name Missing'
        }
    };

    function renderShallow() {
        wrapper = shallow(<UserForm
            labels={labels}
            formFields={formFields}
            errorMessages={errorMessages}
        />);
    }
    it('should render with props(snapshot)', () => {
        renderShallow();
        expect(wrapper).toMatchSnapshot();
    });

    it('should test showModal method', () => {
        const mockSetShowModal = jest.fn();
        React.useState = jest.fn(() => [false, mockSetShowModal]);

        renderShallow();
        expect(mockSetShowModal).toHaveBeenCalledWith(true);
    });
});

Error I am getting -

Expected mock function to have been called with:
      [true]
    But it was not called.

Let me know how can i test the showModal, closeModal and handleSubmit methods in a functional component.

1 Answers

Generally, functional components in React aren't meant to be tested in that way. The React team are suggesting that you use the approach of React Testing Library which is more focused on the actual user interface scenarios. Instead of testing React component instances, you're testing DOM nodes.

This is the main reason why people are moving away from Enzyme and starting to use RTL, because you want to avoid testing implementation details as much as you can.

Related