Search code examples
reactjsunit-testingjestjsenzymespy

Spying on React child component method


I am trying to test my React component with jest and enzyme. I have a form component that uses react-skylight component. I am triggering .show() function on form submit and just when response from server is successful.

My test is currently like this:

import MyForm from './MyForm';
import Popup from 'react-skylight';

describe('<MyForm />', () => {
    it('should show popup on success', () => {
        const popupShowSpy = jest.spyOn(Popup.prototype, 'show');
        const myForm = mount(<MyForm />);
        myForm.update();

        myForm.find('form').simulate('submit');
        expect(popupShowSpy).toHaveBeenCalled();
    });
});

but I am getting an error when I run tests:

expect(jest.fn()).toHaveBeenCalled()

Expected mock function to have been called.

I found here discusion about similar problem, but for me it is not working.


Solution:

Problem was with axios module. It was updating the component, but the response taht was mocked was not resolved, so thanks to this post here, I've managed to write tests. And I wrapped the child components function call in parent component own function and spied on that parent function.

import MyForm from './MyForm';
import Popup from 'react-skylight';

describe('<MyForm />', () => {
    it('should show popup on success', async() => {
        const popupShowSpy = jest.spyOn(MyForm.prototype, 'showPopup');
        const myForm = mount(<MyForm />);

        const response = Promise.resolve({
          data: {
              message: 'Error: some error'
          },
          status: 400
        });
        axios.post = jest.fn(() => response);
        myForm.find('form').simulate('submit');
        await response;
        myForm.update(); // <- child component is rendered correctly
        expect(popupShowSpy).toHaveBeenCalled();
    });
});

Solution

  • Solution:

    Problem was with axios module. It was updating the component, but the response that was mocked was not resolved, so thanks to this post here, I've managed to write tests. And I wrapped the child components function call in parent component own function and spied on that parent function.

    import MyForm from './MyForm';
    import Popup from 'react-skylight';
    
    describe('<MyForm />', () => {
        it('should show popup on success', async() => {
            const popupShowSpy = jest.spyOn(MyForm.prototype, 'showPopup');
            const myForm = mount(<MyForm />);
    
            const response = Promise.resolve({
              data: {
                  message: 'Error: some error'
              },
              status: 400
            });
            axios.post = jest.fn(() => response);
            myForm.find('form').simulate('submit');
            await response;
            myForm.update(); // <- child component is rendered correctly
            expect(popupShowSpy).toHaveBeenCalled();
        });
    });