Value returned from hook during testing stays the same all the time

Viewed 13

Trying to create useFetchData test but something is wrong and value returned from hook is initial value all the time. It doesnt change even after await waitForNextUpdate(). Does anyone see any problem? Because since its the first time I am doing test for a hook I don't even where to look for one.

test

import { renderHook } from "@testing-library/react-hooks";
import useFetchData from "./useFetchData";

const fakeCountries = [
  { name: "Cameroon", population: 1000, area: 100, region: "Africa" },
  { name: "Hong Kong", population: 100, area: 3000, region: "Asia" },
  { name: "Afghanistan", population: 3000, area: 1000, region: "Asia" },
  { name: "Barbados", population: 2000, area: 500, region: "Americas" },
  { name: "Germany", population: 1000, area: 100, region: "Europe" },
  { name: "France", population: 100, area: 3000, region: "Europe" },
  { name: "China", population: 3000, area: 1000, region: "Asia" },
  { name: "Brasil", population: 2000, area: 500, region: "Americas" },
];

afterEach(() => {
  global.fetch.mockClear();
});

afterAll(() => {
  global.fetch.mockRestore();
});

describe("useFetchData", () => {
  it("should return data after fetch", async () => {
    jest.spyOn(global, "fetch").mockImplementation(() => {
      Promise.resolve({
        json: () => Promise.resolve(fakeCountries),
      });
    });

    const { result, waitForNextUpdate } = renderHook(() =>
      useFetchData("lorem")
    );

    expect(result.current.countries).toEqual([]);
    expect(result.current.loading).toBeTruthy();

    await waitForNextUpdate();

    expect(result.current).toMatchObject({
      countries: fakeCountries,
      loading: false,
    });
  });
});

hook

import { useState, useEffect } from "react";
import { toast } from "react-toastify";


const useFetchData = (url) => {
  const [countries, setCountries] = useState([]);
  const [loading, setLoading] = useState(false);

  const fetchData = async () => {
    setLoading(true);
    try {
      const response = await fetch(url);
      if (response.ok) {
        const data = await response.json();
        setCountries(data);
      } else {
        throw response.status;
      }
    } catch (err) {
      toast(
        `Unexpected problem occurred(${err}). Cannot fetch data. Please try again later.`
      );
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchData();
  }, [url]);

  const value = { countries, loading };
  return value;
};
export default useFetchData;
0 Answers
Related