Karan Kumar
Karan Kumar

Reputation: 3176

Jest unable to mock a function inside FC

I need to spy on the function 'fetchPosts' to write unit test to check it is being triggered.

I am new to jest world, would appreciate the help.

Component::

import React from 'react';
import { useDispatch } from 'react-redux';
import { fetchPostAction } from '../../actions/postsAction';

const Button = () => {
    const dispatch = useDispatch();
    const fetchPosts = () => {
        dispatch(fetchPostAction());
    };

    return (
        <button
            onClick={() => fetchPosts()}
            className="btn btn-primary "
            data-test="Button">
            Fetch posts
        </button>
    );
};

export default Button;

I want a way to spy on that function and simulate it for unit test

Test:

describe('Button Component', () => {
    let component;
    let spy;
    let mockFetchPosts = jest.fn();
    beforeEach(() => {
        component = setup();
        spy = jest.spyOn(Button, 'fetchPosts');
        spy.mockReturnValue(mockFetchPosts);
    });

    it('Should render without failing', () => {
        const buttonComponent = findByTestAttr(component, 'Button');
        expect(buttonComponent.length).toEqual(1);
    });

    it('Should dispatch action when clicked', () => {
        const buttonComponent = findByTestAttr(component, 'Button');
        buttonComponent.simulate('click');
        expect(spy).toHaveBeenCalledTimes(1);  // failing 
    });
});

Error:

Cannot spy the fetchPosts property because it is not a function; undefined given instead

Upvotes: 0

Views: 543

Answers (1)

lissettdm
lissettdm

Reputation: 13080

Button.prototype.fetchPosts is undefined, jest can't spy on an undefined value. Instead of spy fetchPosts you can spy the axios call or fetchPostActionfunction:

import axios from "axios";

jest.mock("axios");
axios.get = jest.fn(()=> Promise.resolve({}));

it('Should dispatch action when clicked', () => {
    const buttonComponent = findByTestAttr(component, 'Button');
    buttonComponent.simulate('click');
    expect(axios.get).toHaveBeenCalledTimes(1);
});

Or:

import * as postActions from "../../actions/postsAction";
    
it("Should dispatch action when clicked", async () => {
  const spyPostAction = jest.spyOn(postActions, "fetchPostAction")
  const buttonComponent = findByTestAttr(component, "Button");
  buttonComponent.simulate("click");
  expect(spyPostAction).toHaveBeenCalledTimes(1);
});

Upvotes: 1

Related Questions