When I test a mock of a submit handler with two functions in it, why doesn't the second function get called?

83 Views Asked by At

I have a submit handler in a React form component that does the following onSubmit: registerForm/index.js

import { loginFunction, registerFunction } from "../../actions";
//within registerform function
const handleSubmit = async(e) => {
        e.preventDefault();
        setErrorMessage('')
        await registerFunction(e);
        await loginFunction(e);
        ...
}

I have mocked the two functions in a test file and tested them with the code below: registerForm/registerForm.test.js

import RegisterForm from ".";
import { registerFunction, loginFunction } from "../../actions";
import 'react-router-dom'
import { fireEvent } from "@testing-library/react";

jest.mock('../../actions', () => ({
    loginFunction:jest.fn(),
    registerFunction:jest.fn(),
}))

describe('Unit test of registration form', function() {
    it('should register', () => {
        const {container} = render(< RegisterForm/>)
        fireEvent.submit(container.querySelector('.submit')) 
        expect(registerFunction).toBeCalledTimes(1) // this passes 
        expect(loginFunction).toBeCalledTimes(1) // this fails
    })
})

I have removed the second line and the test passes so I know the submit handler is called but I was wondering why the second function doesn't get called.

I have also tested the loginFunction on a different react form component with a submit handler and the mocked function gets called for that test

loginForm/index.js

import { loginFunction } from "../../actions";
//within loginform function
const handleSubmit = async(e) => {
        e.preventDefault();
        setErrorMessage('')
        await registerFunction(e);
        await loginFunction(e);
        ...
}

loginForm.tes.js

import LoginForm from ".";
import { loginFunction } from "../../actions"
import { fireEvent } from "@testing-library/react";

jest.mock('../../actions', () => ({
    loginFunction:jest.fn()
}))

describe('Unit test of login form', function() {
    it('should login', () => {
        const {container} = render(<LoginForm />)
        fireEvent.submit(container.querySelector('.submit'))
        expect(loginFunction).toBeCalledTimes(1) //this passes 
    })
})
1

There are 1 best solutions below

3
On

Use waitFor in order to let the asynchronous operations finish and make the mocks return a Promise

jest.mock('../../actions', () => ({
    loginFunction:jest.fn(() => Promise.resolve({data: 'data'}),
    registerFunction:jest.fn(() => Promise.resolve({ hello: "world" }),
}))



describe('Unit test of registration form', function() {
    it('should register', async () => {
        const {container} = render(< RegisterForm/>)
        fireEvent.submit(container.querySelector('.submit')) 
        await waitFor(() => {
          expect(registerFunction).toBeCalledTimes(1) 
          expect(loginFunction).toBeCalledTimes(1) 
        })
    })
})