-
-
Notifications
You must be signed in to change notification settings - Fork 22
Description
Sorry, this is quite a tricky bug to narrow down as there are lots of variables involved, but hopefully there's enough here for a hint of the problem
Describe the bug
We have upgraded from React Native 0.68 and jest 26-29. Quite a big jump, but we managed to get most of our 700 tests working after tweaking some of the fake timer logic.
We're having problems in two suites, both of which involve the bundle splitter layer.
If I import a component using bundle splitter, the useEffect in my component never seems to run. I have tried all manner of jest.runOnlyPendingTimers etc, and have also tried real timers, increasing jest timeouts etc and nothing seems to get this to work. If I call React Native test library rerender it then calls useEffect once, but this is obviously a hack.
The test then works fine when I import the component normally.
Code snippet
Component file
const SignUpScreen = () => {
//This render logic successfully runs in my test
React.useEffect(() => {
//but this useEffect never does
triggerTracking()
}, [])
const triggerTracking = ()=>{
myTrackingFn()
}
Navigation layer file
const SignUpScreen = register({
loader: () => require('Screens/SignUpScreen'),
group: ONBOARDING,
})
// import SignUpScreen from 'Screens/SignUpScreen' // If I comment the above and use this, everything works as expected
Test file
const component = <Navigator {...props} />
const renderedComponent = await waitFor(() => render(component))
// Check screen has rendered
const image = await renderedComponent.findByTestId(SIGNUP_IMG_TEST_ID)
expect(image).toBeTruthy()
// Initial Paywall
act(() => {
// Nothing in here causes the useEffect to fire...have tried many many combinations!
jest.runOnlyPendingTimers()
//jest.runAllTimers Also doesn't work
// renderedComponent.rerender(component) //This gets the useEffect to fire once
})
// This never triggers, even with real timers, because the useEffect never runs
await waitFor(() => expect(myTrackingFn).toHaveBeenCalled(), {
timeout: 40000,
})
I can fix it using this mock:
const RNBundleSplitter = jest.requireActual('react-native-bundle-splitter')
module.exports = {
...RNBundleSplitter,
register: (props: any) => {
const Component = props.loader().default
return Component
},
}
but would be nice if I could test the real behaviour in my tests.
Expected behavior
The useEffect in the inner component should render in tests
Smartphone (please complete the following information):
- Desktop OS MacOS 14.4
- Device: n/a
- JS engine: Jest (node)
- Library version 2.2.3
Any idea what this could be?