Can React Testing Library find element after state change?

I'm absolutely new to react testing, learning from a playlist in youtube.

In this very moment of the tutorial, the instructor tests a component, which:

  1. has a useEffect.
  2. inside a useEffect, there is an axios.get
  3. state is updated with api response.
  4. state data is turned to elements (each has data-testid attribute equal to follower-item-{someNumber}.

The objective of the test is to find a data element. . despite that i'm almost coping his code, his test passes, but mine doesn't. seems like the test runs before data fetching.

the component:

export default function FollowersList() {
  const [followers, setFollowers] = useState([]);

  useEffect(() => {
    fetchFollowers();
  }, []);
  const fetchFollowers = async () => {
    const { data } = await axios.get("https://randomuser.me/api/?results=5");
    setFollowers(data.results);
  };

  return (
    <div className="followerslist-container">
      <div>
        {followers.map((follower, ind) => (
          <div className="follower-item" data-testid={`follower-item-${ind}`}>
            <img src={follower.picture.large} />
            <div className="followers-details">
              <div className="follower-item-name">
                <h4>{follower.name.first}</h4> <h4>{follower.name.last}</h4>
              </div>
              <p>{follower.login.username}</p>
            </div>
          </div>
        ))}
      </div>
      <div className="todo-footer">
        <Link to="/">Go Back</Link>
      </div>
    </div>
  );
}

The test:

const MockFollowersList = () => {
  return (
    <BrowserRouter>
      <FollowersList />
    </BrowserRouter>
  );
};

describe("followers list", () => {
  it("should render follower items", async () => {
    render(<MockFollowersList />);
    let el = await screen.findByTestId("follower-item-0");

    expect(el).toBeInTheDocument();
  });
});

result:

 Unable to find an element by: [data-testid="follower-item-0"]

<body>
  <div>
    <div
      class="followerslist-container"
    >
      <div />
      <div
        class="todo-footer"
      >
        <a
          href="/"
        >
          Go Back
        </a>
      </div>
    </div>
  </div>
</body>

Solution 1:

The problem is that you don't mock data. Try using https://www.npmjs.com/package/nock#debugging or something similar.

I recommend you to install and use eslint rule for testing library: https://github.com/testing-library/eslint-plugin-testing-library. This rule could help you avoid a common mistakes.