Description
Describe the bug
This is an image gallery and I'm confident it's working correctly. It runs fine in the simulator. I've tried to variations of the same test:
test('main image should display', async () => {
const { findByTestId } = render(<ImageGallery images={images} />);
const mainImage = await findByTestId('largeImage');
expect(mainImage).toBeDefined();
});
and
test('main image should display', async () => {
const { getByTestId } = render(<ImageGallery images={images} />);
await waitFor(() => {
expect(getByTestId('largeImage')).toBeDefined();
});
});
In both instances the test fails with: Unable to find node on an unmounted component.
Inside my tsx file I have a useEffect hook that preloads all the images before displaying them. It then updates state (which causes another unrelated issue)
// Cache all images in the gallery after initial component render
useEffect(() => {
if (!imagesReady) {
const loadedImages: Array<Promise<boolean>> = images.map((image) => {
return Image.prefetch(image.url);
});
Promise.all(loadedImages).then((imageLoadStatus) => {
// Filter out any images that didn't properly load
images = images.filter((_, index) => imageLoadStatus[index]);
setActiveImage(images[0]);
setImagesReady(true);
});
}
});
Then in the return:
// Render either loading indicator or image gallery conditionally.
if (!imagesReady) {
return (
<Container>
<ActivityIndicator size="small" color="#202020" testID="loading" />
</Container>
);
}
return (
<Container testID="galleryWrapper">
<LargeImage source={{ uri: activeImage.url }} testID="largeImage" />
<ThumbnailList
horizontal
data={images}
renderItem={thumbnail}
keyExtractor={(image) => image.id}
showsHorizontalScrollIndicator={false}
/>
</Container>
);
Like I said, the code is working fine in the simulator and takes way less than 4.5 seconds to load. For testing purposes though, I added a jest.settimeout(10000) to make sure it wasn't a timing issue.
Expected behavior
I expect findBy to wait until the element with testID 'largeImage' appears on the screen, then I expect it to find and return it.
I expect waitFor to wait until the expectation is successful and then allow the test to proceed.
Steps to Reproduce
Most of the code above should help you reproduce. But:
- Create a component that updates state in useEffect().
- Attempt to use findBy or waitFor to grab a component that appears after the state update.
npmPackages:
@testing-library/react-native: ^7.2.0 => 7.2.0
react: 16.13.1 => 16.13.1
react-native: https://github.com/expo/react-native/archive/sdk-40.0.1.tar.gz => 0.63.2