React useEffect hook jest unit test não confirma que a função prop é chamada
Estou tentando escrever um teste de unidade para verificar se uma função (passada como um prop) é chamada se outro prop for verdadeiro no gancho useEffect. O teste de unidade falha ao confirmar que a função (simulada) é chamada no gancho useEffect, mas pode confirmar que uma função que é spyOn de um módulo importado é chamada. Alguém sabe qual pode ser o problema? Obrigado!
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 />)
});
Teste de unidade:
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
});
Parece que tem algo a ver com useCallback com useEffect. Se eu remover o useCallback e adicionar a lógica dentro de useEffect, ele pode capturar someReduxDispatchFuncMockfoi chamado.
Respostas
Não acho que o problema seja de useCallbackou useEffect. O problema é mais provável que seu retorno de chamada tenha uma função assíncrona, o que significa que precisa de tempo para ser resolvido.
Para isso, você deve fazer seu teste assíncrono e esperar que seja resolvido da seguinte forma:
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();
});