Jest warning about an uninitialized event


I joined a project with lots of flaking unit tests causing intermittent pipeline failures. Started fixing problems. Got stuck with an uninitialized event problem.
We have a piece of code with a simple ternary implemented below:

export default function ReturnToLastSearch({ href, onClick }: Props): JSX.Element {
  const router = useRouter();

  useEffect(() => {
    const handleStart: any = async (url: string) => {
      if (window && url.indexOf('listings') > 0) {
        await trackReturnToSeachClick(url);
      }
    };
    const handleComplete: any = () => {};
    router.events.on('routeChangeStart', handleStart);
    router.events.on('routeChangeComplete', handleComplete);
    router.events.on('routeChangeError', handleComplete);

    // Cleanup event listeners
    return (): void => {
      router.events.off('routeChangeStart', handleStart);
      router.events.off('routeChangeComplete', handleComplete);
      router.events.off('routeChangeError', handleComplete);
    };
  }, [router]);

  const { t } = useTranslation();
  const urlOnClick = async (e: React.MouseEvent): Promise<void> => {
    e.persist();
    e.target.dispatchEvent(e.nativeEvent);
  };

  return (
    <div className="return-to-search">
      <h3>{t('favorites.favoriteVehicles')}</h3>
      <p>{t('favorites.description')}</p>
      <Link href={href}>
        <a className="button" onClick={!onClick ? urlOnClick : onClick}>
          {t('favorites.returnToLastSearch')}
        </a>
      </Link>
      ...

I have some unit tests covering this piece, coded as:

describe('on click', () => {
  it('when onClick is defined uses onClick', () => {
    const call = jest.fn();
    const { getByText } = render(<ReturnToLastSearch href="foo" onClick={call} />);
    getByText(i18n.t('favorites.returnToLastSearch') as string).click();

    expect(trackReturnToSeachClick).not.toHaveBeenCalled();
    expect(call.mock.calls.length).toBe(1);
  });

  it('when onClick is not defined tracks the return click', () => {
    // eslint-disable-next-line
    const useRouter = jest.spyOn(require('next/router'), 'useRouter');
    useRouter.mockImplementation(() => ({
      route: '/',
      pathname: '',
      query: '',
      asPath: '',
      push: jest.fn(),
      events: {
        on: jest.fn(async (url) => trackReturnToSeachClick(url)),
        off: jest.fn(),
      },
      beforePopState: jest.fn(() => null),
      prefetch: jest.fn(() => null),
    }));

    const { getByText } = render(<ReturnToLastSearch href="foo" />);
    getByText(i18n.t('favorites.returnToLastSearch') as string).click();

    expect(trackReturnToSeachClick).toHaveBeenCalled();
  });
});

Tests pass, but the second one raises the below warning:

(node:36379) UnhandledPromiseRejectionWarning: InvalidStateError: Tried to dispatch an uninitialized event
    at HTMLAnchorElementImpl.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:74:13)
    at HTMLAnchorElementImpl.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
    at HTMLAnchorElement.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
    at urlOnClick (...web/components/Favorites/ReturnToLastSearch.tsx:64:14)
    at HTMLUnknownElement.callCallback (...web/node_modules/react-dom/cjs/react-dom.development.js:3945:14)
    at invokeEventListeners (...web/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:193:27)
    at HTMLUnknownElementImpl._dispatch (...web/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:119:9)
    at HTMLUnknownElementImpl.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/events/EventTarget-impl.js:82:17)
    at HTMLUnknownElementImpl.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/nodes/HTMLElement-impl.js:30:27)
    at HTMLUnknownElement.dispatchEvent (...web/node_modules/jsdom/lib/jsdom/living/generated/EventTarget.js:157:21)
(node:36379) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 1)
(node:36379) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

I tried fireEvent from @testing-library/user-event and the same thing is happening. How do I fix the warning?

Source: React – Stack Overflow

October 3, 2021
Category : News
Tags: javascript | jestjs | mocking | reactjs | unit testing

Leave a Reply

Your email address will not be published. Required fields are marked *

Sitemap | Terms | Privacy | Cookies | Advertising

Senior Software Developer

Creator of @LzoMedia I am a backend software developer based in London who likes beautiful code and has an adherence to standards & love's open-source.