Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mock useEffect async calls with react-native-testing-library?

I'm trying to test the screen that has useEffect hook with the following:

export const SomeScreen: React.FC<Props> = ({}) => {

  const [isSensorAvailable, setIsSensorAvailable] = useState(false);

  useEffect(() => {
    const isSensorAvailableCheck = async () => {
      try {
        await FingerprintScanner.isSensorAvailable();
        setIsSensorAvailable(true);
      } catch (error) {
        console.log(error);
      }
    };

    isSensorAvailableCheck();
  }, []);
  
  ...
   Here goes code that renders View if the sensor is available
  ...
}

And I'm trying the following test:


import {default as FingerprintScannerMock} from 'react-native-fingerprint-scanner';

jest.mock('react-native-fingerprint-scanner');

(FingerprintScannerMock.isSensorAvailable as jest.Mock).mockResolvedValue(true);

const createTestProps = (props: Object) => ({
  navigation: {
    navigate: jest.fn(),
  },
  ...props,
});

describe('Testing some screen', () => {

   test('testing some functionalities', async () => {
     let props: any;
    props = createTestProps({});

    const component = render(
      <Provider store={store}>
        <RegisterPasswordScreen {...props} />
      </Provider>,
    );

    const {getByText, getByTestId, getAllByTestId} = component;

    const container = getByTestId('containerId');

    expect(container).toBeTruthy();
   });

});

But this container is never found because setIsSensorIsAvailable never sets the value to true because of the following error:

An update to SomeScreen inside a test was not wrapped in act(...).

I tried everything even like this:


  const component = await waitFor(() =>
       render(<Provider store={store}>
         <RegisterPasswordScreen {...props} />
        </Provider>,
       );
   ); 

But when I run this test it never ends. Tried also to wrap it with act(...) but that does not work either, then the error is following: Can't access .root on unmounted test renderer.

Any help appreciated, thanks!

like image 329
moh warf Avatar asked Mar 13 '26 22:03

moh warf


2 Answers

Had a similar issue

Wrapping the component using act(https://reactjs.org/docs/testing-recipes.html#act) solved my issue

Using create to wrap your component for react native instead of using a typical render method wrapped in act

import { act, create } from 'react-test-renderer';


it('test', async () => {
    await act(async () => {
        create(<ComponentWithAsyncUseEffect />);
    });
})
like image 133
Elvis Enyi Avatar answered Mar 16 '26 10:03

Elvis Enyi


I ended up using findByTestId rather than getByTestId and now it works well.

like image 28
moh warf Avatar answered Mar 16 '26 10:03

moh warf



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!