'Need do write unit tests with jest for react app, that uses okta, but getting warning

import { SecureRoute, Security, LoginCallback } from '@okta/okta-react';
import React, { useMemo } from 'react';
import { Route, Switch } from 'react-router-dom';

import { OktaAuth, toRelativeUrl } from '@okta/okta-auth-js';
import Comp from './Comp';

const config = {oidc: {....}};

const AppRouter = () => {
  const oktaAuth = useMemo(() => new OktaAuth(config.oidc), []);
  const restoreOriginalUri = async (sth, originalUri) => {
    history.replace(toRelativeUrl(originalUri || '/', 'some-path-here'));
  };

  return (
    <Security oktaAuth={oktaAuth} restoreOriginalUri={restoreOriginalUri}>
      <Switch>
        <SecureRoute path="/" exact component={Comp} />
        <Route path="/login/callback" component={LoginCallback} />
      </Switch>
    </Security>
  );
};
export default AppRouter;

I have this in my app... how to write unit tests for it if I have the following warning?

Warning: An update to Security inside a test was not wrapped in act(...).



Solution 1:[1]

The thing is you have to await for Okta asynchronous updates in the component.

You could just wrap your "expects" block with await waitFor(() => { } assuming you're using React Testing Library.

Example:

await waitFor(() => {
    expect(getAllByText(/Home/i)[0]).toBeInTheDocument;
    expect(getAllByText(/Home/i)[1]).toBeInTheDocument;
});

Solution 2:[2]

The waitFor thing doesn't seem to work. The okta Security, SecureRoute, and LoginCallback, all trigger test failures (element is undefined, etc).

I got it running this way: I figure I don't need to test any of those elements, I just need to test if my app is rendering. So I mocked everything and this passed the test without undue hackery.

Hope this helps, I see a lot of people out there struggle with this one:

import {cleanup, screen, waitFor} from '@testing-library/react';
import App from './App';
import {render} from "react-dom";
import {BrowserRouter} from "react-router-dom";

jest.mock('@okta/okta-react', () => {
  return ({
    useOktaAuth: () => ({
      authState: {isAuthenticated: true},
      authService: {handleAuthentication: jest.fn()},
      oktaAuth: {getUser: () => new Promise((resolve, reject) => { resolve('foo')})},
    }),
    withOktaAuth: (x: any) => x,
    Security: () => <div></div>,
    SecureRoute: () => <div></div>,
    LoginCallback: () => <div></div>
  });
});

describe('<App />', () => {
  let container: any = null;
  beforeEach(() => {
    container = document.createElement('div');
    document.body.appendChild(container);
  });

  afterEach(cleanup);

  test("Render App", async () => {
    render(<BrowserRouter><App /></BrowserRouter>, container);
    const comp = await screen.findByTestId('App', container);
    expect(comp).toBeInTheDocument();
  });
});

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Eduardo Favarato
Solution 2 Tim Consolazio