The approach I'm using for testing asynchronous components with useEffect
that triggers a rerender with setState
is to set the test case up as normal, but use waitFor
or findBy
to block assertions until the component rerenders with the fetched data.
Here's a simple, runnable example:
import React, {useEffect, useState} from "react";
import {FlatList, Text} from "react-native";
import {render} from "@testing-library/react-native";
const Posts = () => {
const [posts, setPosts] = useState(null);
useEffect(() => {
const url = "https://jsonplaceholder.typicode.com/posts";
fetch(url).then(res => res.json()).then(setPosts);
}, []);
return !posts ? <Text>loading</Text> : <FlatList
testID="posts"
data={posts}
renderItem={({item: {id, title}, index}) =>
<Text testID="post" key={id}>{title}</Text>
}
/>;
};
describe("Posts", () => {
beforeEach(() => {
global.fetch = jest.fn(url => Promise.resolve({
ok: true,
status: 200,
json: () => Promise.resolve([
{id: 1, title: "foo title"},
{id: 2, title: "bar title"},
])
}));
});
it("should fetch posts", async () => {
const {findAllByTestId} = render(<Posts />);
const posts = await findAllByTestId("post", {timeout: 500});
expect(posts).toHaveLength(2);
expect(posts[0]).toHaveTextContent("foo title");
expect(posts[1]).toHaveTextContent("bar title");
expect(fetch).toHaveBeenCalledTimes(1);
});
});
This doesn't give me any act
warnings, but I've had my share of those. This open GitHub issue appears to be the canonical resource.
Packages used:
{
"dependencies": {
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-native": "^0.64.0",
"react-native-web": "^0.15.6"
},
"devDependencies": {
"@babel/core": "^7.13.15",
"@testing-library/jest-native": "^4.0.1",
"@testing-library/react-native": "^7.2.0",
"babel-jest": "^26.6.3",
"jest": "^26.6.3",
"metro-react-native-babel-preset": "^0.65.2",
"react-test-renderer": "^17.0.2"
}
}
And in the Jest config:
setupFilesAfterEnv: ["@testing-library/jest-native/extend-expect"],
for the .toHaveTextContent
matcher. Or you can use an import:
import "@testing-library/jest-native/extend-expect";