React-native-testing-library: Async data load with `useEffect` still triggers `act` warning

Created on 9 Jul 2019  ·  4Comments  ·  Source: callstack/react-native-testing-library

Versions

  • React: 16.8.6
  • React Native: 0.60.0
  • RNTL: 1.10.0
  • React-Test-Renderer: 16.8.6

Description

I'm attempting to test asynchronous data loads within useEffect, and I'm getting that old React "An update to [your component] inside a test was not wrapped in act(...)"

I see in #111 that changes were merged related to adding act to various RNTL calls, but that doesn't seem to address this case.

I finally dug through the master React issue on the act warnings, and my main takeaways are:

  • For now, use Jest's useFakeTimers and runAllTimers—this is the way Facebook does it and it should work.
  • In React 16.9.0 (not released in production yet either for the web or for React Native), act has been updated to support async/await, and so you will be able to do all your stuff in the test inside act, and assert outside of it. Just not released yet.

I tried the "the way Facebook does it" fix and it doesn't seem to work (see reproducible demo below). Do you know of a way to get the test to correctly run this code through act such that I don't get the warning?

Reproducible Demo

https://github.com/CodingItWrong/TestingRNHooks

Most helpful comment

I added this to my jest setup file, maybe someone find it useful:

const originalConsoleError = console.error;

console.error = (...args) => {
  if (
    !args[0].startsWith(
      'Warning: An update to %s inside a test was not wrapped in act(...).',
    )
  ) {
    originalConsoleError(...args);
  }
};

All 4 comments

Gonna have a look tomorrow, thanks for the report!

Unfortunately, there's nothing on our side we can do. This is a react-test-renderer issue and needs to be fixed upstream, as said by Sunil: https://github.com/facebook/react/issues/14769#issuecomment-462528230. You can apply various workarounds in your testing environment though:

  • mock console.error and filter out those messages for now
  • transform async/await to global.Promise and mock it so that it wraps stuff with act, ideally as a helper imported only in React-based tests

However, personally, I try to ignore these warnings 🤷‍♂.

Also, please use await waitForElement(() => getByText('foo')) instead of await flushMicrotasksQueue() – it's easier to read intentions and you don't need to care if async actions take 1 or more microtask ticks.

I added this to my jest setup file, maybe someone find it useful:

const originalConsoleError = console.error;

console.error = (...args) => {
  if (
    !args[0].startsWith(
      'Warning: An update to %s inside a test was not wrapped in act(...).',
    )
  ) {
    originalConsoleError(...args);
  }
};

Thanks @neiker, appreciated!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

entiendoNull picture entiendoNull  ·  6Comments

kblankenship1989 picture kblankenship1989  ·  3Comments

acollazomayer picture acollazomayer  ·  3Comments

ptrckhjnl picture ptrckhjnl  ·  6Comments

Andarius picture Andarius  ·  9Comments