Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Asyncs utils: You called act(async () => ...) without await #825

Open
enzzoperez opened this issue Apr 13, 2022 · 5 comments
Open

Asyncs utils: You called act(async () => ...) without await #825

enzzoperez opened this issue Apr 13, 2022 · 5 comments
Labels
question Further information is requested

Comments

@enzzoperez
Copy link

enzzoperez commented Apr 13, 2022

Hi!, Im starting to test my hooks (in a POC stage), I have a simple test that works but I get the following warning that I dont know how can it solved 馃

Warning: You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);

      at console.error (node_modules/@testing-library/react-hooks/lib/core/console.js:19:7)
      at printWarning (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:68:30)
      at error (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:44:5)
      at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15297:13
      at tryCallOne (node_modules/promise/lib/core.js:37:12)
      at node_modules/promise/lib/core.js:123:15
      at flush (node_modules/asap/raw.js:50:29)

this is my hook

import {useState, useEffect} from 'react';

const defaultValue = {data: 'Default'};

const useRemoteData = ({data}: any) => {
  const [response, setResponse] = useState<any>();
  const [error] = useState<any>();
  const [isLoading] = useState(true);

  useEffect(() => {
    data ? setTimeout(() => setResponse(data), 500) : setResponse(defaultValue);
  }, [data]);

  return {response, error, isLoading};
};

export default useRemoteData;

and in my test file, Im trying to test that if the props change, the data will change too

  import {renderHook} from '@testing-library/react-hooks';
  import useRemoteData from './useRemoteData';


  it('Init error false ', async () => {
    const {result, waitFor, rerender} = renderHook(
      ({data}) => useRemoteData({data}),
      {
        initialProps: {data: 'first render'},
      },
    );

    await waitFor(() => {
      expect(result.current.response).toEqual('first render');
    });

    rerender({data: 'second render'});

    await waitFor(() => {
      expect(result.current.response).toEqual('second render');
    });
  });

Am I forgetting something in the test file?

Thanks!

@enzzoperez enzzoperez added the question Further information is requested label Apr 13, 2022
@tcank
Copy link

tcank commented May 4, 2022

Same issue here! The problem comes when using more than one awaited waitFor in the same it
Already read the act behavior in this PR https://github.com/callstack/react-native-testing-library/pull/969/files and tried all the suggestions of this issue callstack/react-native-testing-library#379.

@tcank
Copy link

tcank commented May 6, 2022

We can fix the problem using the solution proposed on https://stackoverflow.com/questions/64952449/react-native-testing-act-without-await/69201830#69201830
It seems that react-native jest preset is replacing global Promise implementation (2020 issue facebook/react-native#29303) and this leads to the act-await warning.

The patch consists in add one previous preset and one post preset in order to save the original implementation and restore it after react-native preset is set. We do this and found that many tests started to fail (many), and in order to not debug each one, we change the patch to save the original implementation (in first preset) in global.nativePromise and polyfilled in global.polyfilledPromise (in last preset). Later, when we need to fix the Act Await warning, we swap the implementations only for a specific test suite calling fixActAwaitWarning:

const fixActAwaitWarning = (): void => {
  beforeAll(() => {
    global.Promise = global.nativePromise;
  });
  afterAll(() => {
    global.Promise = global.polyfilledPromise;
  });
};

@mpeyper
Copy link
Member

mpeyper commented May 7, 2022

Thank you for your effort and investigation into this @tcank.

@farid-mitchi
Copy link

We can fix the problem using the solution proposed on https://stackoverflow.com/questions/64952449/react-native-testing-act-without-await/69201830#69201830 It seems that react-native jest preset is replacing global Promise implementation (2020 issue facebook/react-native#29303) and this leads to the act-await warning.

The patch consists in add one previous preset and one post preset in order to save the original implementation and restore it after react-native preset is set. We do this and found that many tests started to fail (many), and in order to not debug each one, we change the patch to save the original implementation (in first preset) in global.nativePromise and polyfilled in global.polyfilledPromise (in last preset). Later, when we need to fix the Act Await warning, we swap the implementations only for a specific test suite calling fixActAwaitWarning:

const fixActAwaitWarning = (): void => {
  beforeAll(() => {
    global.Promise = global.nativePromise;
  });
  afterAll(() => {
    global.Promise = global.polyfilledPromise;
  });
};

Do you mean to change the content of restore-promise.js like this:

global.polyfilledPromise = Promise;

I found it really works!

@robbporto
Copy link

robbporto commented Apr 11, 2023

This is still happening. It only happens when I use more than one awaited waitFor in the same it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Further information is requested
Projects
None yet
Development

No branches or pull requests

5 participants