Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React useEffect hook jest unit test doesn't confirm function prop is called

I'm trying to write a unit test to check that a function (passed as a prop) gets called if another prop is true in useEffect hook. The unit test fails to confirm that the (mocked) function is called in the useEffect hook, but it can confirm that a function that is spyOn from an imported module is called. Does anyone know what might be the issue? Thanks!

import {getUser} from './Auth';
export function ComponentA({
  shouldRetryExport,
  someReduxDispatchFunc,
}) {

  const handleExport = useCallback(async () => {
    const user = await getUser();
    someReduxDispatchFunc();
  }, []);

  useEffect(() => {
    if (shouldRetryExport) {
      handleExport();
    }
  }, [shouldRetryExport]);

  return (<SomeComponent />)
});

Unit test:

import * as Auth from './Auth';

it('should call someReduxDispatchFunc if getUserAuthorization is true', () => {
  const getAuthUserSpy = jest.spyOn(Auth, 'getUser');
  const someReduxDispatchFuncMock = jest.fn();
  const props = {
    someReduxDispatchFunc: someReduxDispatchFuncMock,
    shouldRetryExportWithUserReAuthorization: true,
  };
  enzyme.mount(<ComponentA {...props} />);

  expect(getAuthUserSpy).toHaveBeenCalled(); // works -> returns true
  expect(someReduxDispatchFuncMock).toHaveBeenCalled(); // doesn't work -> returns false
});

It seems like it has something to do with the useCallback with useEffect. If I remove the useCallback and add the logic within to useEffect, it can capture someReduxDispatchFuncMock has been called.

like image 949
PBandJen Avatar asked May 28 '26 14:05

PBandJen


1 Answers

I don't think the problem is from either useCallback or useEffect. The problem is most likely your callback takes an async function which means it needs time to get resolved.

In order to this, you have to make your test as async then wait it to get resolved as following:

it('should call someReduxDispatchFunc if getUserAuthorization is true', async () => {
  const getAuthUserSpy = jest.spyOn(Auth, 'getUser');
  const someReduxDispatchFuncMock = jest.fn();
  const props = {
    someReduxDispatchFunc: someReduxDispatchFuncMock,
    shouldRetryExport: true,
  };
  enzyme.mount(<ComponentA {...props} />);

  // wait for getting resolved
  await Promise.resolve();

  expect(getAuthUserSpy).toHaveBeenCalled();
  expect(someReduxDispatchFuncMock).toHaveBeenCalled();
});
like image 178
tmhao2005 Avatar answered May 31 '26 10:05

tmhao2005



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!