-
Notifications
You must be signed in to change notification settings - Fork 273
Test with suspending component times out with fakeTimers: { enableGlobally: true }
#1347
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Not sure how well RNTL handles React Suspense, I will have to spend some time to check it out. BTW why are you throwing a function returning a promise? Also |
I think it throws a promise, the arrow function is called immediately. I admit it might not be the clearest syntax. |
I encountered the issue initally with React Query btw |
I've started to look into this and it's not easy. I haven't made much progress so far but I did a reproduction of the issue using nearly no code from RNTL: import * as React from 'react';
import { Text, View } from 'react-native';
import Renderer from 'react-test-renderer';
import { getQueriesForElement } from '../..';
jest.useFakeTimers();
test.only('should work', async () => {
let loading = true;
let data: string | undefined = undefined;
const Suspending = () => {
if (loading)
throw (async () => {
return await 'result';
})().then((result) => {
data = result;
loading = false;
return result;
});
return <Text>{data}</Text>;
};
const instance = Renderer.create(
<View>
<React.Suspense fallback={<Text>Loading</Text>}>
<Suspending />
</React.Suspense>
</View>
);
const queries = getQueriesForElement(instance.root);
jest.useRealTimers();
await new Promise((resolve) => setImmediate(resolve));
jest.useFakeTimers();
expect(queries.getByText('result')).toBeTruthy();
}); I'm only using getQueriesForElement but I'm pretty sure it's not the source of this bug. That would mean that the problem lies elsewhere, although I'm not sure yet where, but I'd guess either jest or react-test-renderer Also in both cases the promise resolves correctly but in one case we still see the loading state so it's definitely related to Suspense having a different behavior in both situations somehow |
I've noticed that issue is linked to the faking of fakeTimers: {
enableGlobally: true,
doNotFake: ["setImmediate"],
}, |
@robingullo, @pierrezimmermannbam, @matthieugicquel if I understand the above conclusions, seem to indicate that this is a Jest issue, and not a RNTL one. Do you agree with that conclussion? |
@mdjastrzebski I found a similar issue on the react repo, with a deep analysis. It looks like a more general React / Jest incompatibility. The issue explains how it can fixed by switching to real timers before module imports:
But of course it works only with require... |
I've had to do the same |
Closing as both stale and non-actionable at the moment. There is known workaround (Use |
Describe the bug
I've set up a simple test with a suspending component (no timers, just a return in async / await) that eventually renders a text. The test waits for the text with
await findByText
.With
jest.useFakeTimers()
, the test pass.With
fakeTimers: { enableGlobally: true }
injest.config.js
, the test fails.Expected behavior
The test should pass in both cases.
Steps to Reproduce
jest.config.js
, add the linefakeTimers: { enableGlobally: true }
Versions
npmPackages:
@testing-library/react-native: ^11.4.0 => 11.5.2
react: 18.1.0 => 18.1.0
react-native: 0.70.5 => 0.70.5
react-test-renderer: 18.1.0 => 18.1.0
Note:
I have the same result with RN 0.71.3 and the standard 'react-native' preset.
The text was updated successfully, but these errors were encountered: