How to mock async action call from react component with jest and RTL

Viewed 790

I have a component that when you click a button, it will call an async redux action that makes POST call to api,, and it will resolve if call was successful and reject if not.

import { reduxAction } from 'store/actions';

function TestBtn(props) {
    const { href, action } = props;

    const onClick= () =>
        action ({
            method: 'post',
            path: href
        })
            .then(() => {
                //do something
            })
            .catch(() => {
                //do something
            });

    return (
            <Button
                variant={'outlined'}
                onClick={onClick}
                label='Click'
            />
    );
}

const mapDispatchToProps = dispatch => ({
    action : payload => dispatch(reduxAction(payload))
});

export default connect(null, mapDispatchToProps)(TestBtn);

I would like to test this functional component with Jest and react-testing-library, but I do not know how properly mock this action, so it does not make a real call.

I tried something like this

import React from 'react';

import { render, screen, fireEvent } from 'test-utils';
import '@testing-library/jest-dom';
import TestBtn from 'components';
import * as actions from 'store/actions';

const mockGetData = jest
    .spyOn(actions , 'reduxAction')
    .mockImplementation(() => Promise.resolve());

const href = '/test';

test('acts properly, when click on a button', () => {
    render(<TestBtnhref={href} />);

    fireEvent.click(screen.getByText(/send_to_cc/));
});

But it doesn't work, I receive TypeError: Cannot read property 'then' of undefined

1 Answers

Your mock implementation returns a Promise.resolve() that is going to be resolved to an undefined value. This is the reason you were getting the error. You must give a value as an argument to resolve by the promise.

You could also use .mockResolvedValue() for this. This API is used when you want to return a promise value of an async function to resolve.

import React from 'react';

import { render, screen, fireEvent } from 'test-utils';
import '@testing-library/jest-dom';
import TestBtn from 'components';
import * as actions from 'store/actions';

const mockGetData = jest
    .spyOn(actions , 'reduxAction')
    .mockResolvedValue({ fakeObjectKey1: "anything"}); // here is the change

const href = '/test';

test('acts properly, when click on a button', () => {
    render(<TestBtnhref={href} />);

    fireEvent.click(screen.getByText(/send_to_cc/));
});
Related