Next.js Discord

Discord Forum

Mocking asynchrous react hook vitest issue

Unanswered
Old English Terrier posted this in #help-forum
Open in Discord
Old English TerrierOP
Hi, hoping someone much smarter than me can point me in the right direction on a failing test of mine.

hook.ts
function useFileRetrieval() {
  const [retrieving, setIsRetrieving] = useState(false);
  const [success, setSuccessMessage] = useState<string | null>(null);
  const setError = useSetRecoilState(errorState);
  const authenticationToken = useContext(AuthContext);

  async function retrieveFile(fileLink: string) {
    const fileLinkIncludesHttp = fileLink.toLocaleLowerCase().includes('http');
    const fileLinkIncludesBlob = fileLink.toLocaleLowerCase().includes('blob://');

    if (fileLinkIncludesHttp) {
      window.open(fileLink, '_blank', 'noreferrer');
      return;
    }

    if (fileLinkIncludesBlob) {
      // do nothing as link isn't a web address, and also doesn't contain custom blob string
      return;
    }

    const [index, filename] = fileLink.split('/');

    setIsRetrieving(true);
    try {
      await getFile(index, filename, authenticationToken, setError);
      setError(null);
      setSuccessMessage('File retrieved successfully.');
    } catch (error) {
      setError('Error retrieving file.');
      setSuccessMessage(null);
    } finally {
      setIsRetrieving(false);
    }
  }

  return {
    retrieveFile,
    retrieving,
    success,
  };
}


hook.test.ts
it('should set retrieving to true while retrieving the file and to false after', async () => {
    const { result } = renderHook(() => useFileRetrieval(), { wrapper: Wrapper });
    const { retrieveFile, retrieving } = result.current;

    getFileMock.mockReturnValue(
      new Promise<void>(resolve => {
        setTimeout(() => {
          expect(retrieving).toBe(true);
          resolve();
        }, 100);
      }),
    );

    await act(async () => {
      await retrieveFile('index/fileName');
    });

    expect(retrieving).toBe(false);
  });

1 Reply

Old English TerrierOP
Going through debug mode in vscode I see that everything is called in the correct order.

retrieveFile runs and then when it's call getFile the control flow goes into my mock, the issue is that retrieving value is still false even though previously in retrieveFile setRetrieving(true) was called.