Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
React hook to call an API using fetch with test examples
import React from "react";
import { useDataApi } from "path/to/hoo/useDataApi.jsx";
import "whatwg-fetch";
import { renderHook } from "@testing-library/react-hooks";
import fetchMock from "fetch-mock";
import { act } from "react-test-renderer";
describe("useDataApi", () => {
beforeAll(() => {
global.fetch = fetch;
});
afterAll(() => {
fetchMock.restore();
});
});
import React from "react";
import { useDataApi } from "path/to/hoo/useDataApi.jsx";
import "whatwg-fetch";
import { renderHook } from "@testing-library/react-hooks";
import fetchMock from "fetch-mock";
import { act } from "react-test-renderer";
describe("useDataApi", () => {
beforeAll(() => {
global.fetch = fetch;
});
afterAll(() => {
fetchMock.restore();
});
it("should return error as true if the api error", async () => {
const { result } = renderHook(() => useDataApi());
// Tell the test that any request to 'test.com' should return return a 500 error
fetchMock.mock("test.com", 500);
// Calling the api via the `callApi` function
await act(async () => {
result.current.callApi("test.com");
});
// Data should be null and error should be true
expect(result.current.data).toBe(null);
expect(result.current.error).toBe(true);
});
});
import { useEffect, useState, useRef } from "react";
export const useDataApi = () => {
const firstUpdate = useRef(true);
const [error, setError] = useState(false);
const [apiUrl, setApiUrl] = useState("");
const [data, setData] = useState(null);
useEffect(
() => {
if (!firstUpdate.current) {
fetch(apiUrl)
.then(response => response.json())
.then(response => {
setData(response);
})
.catch(error => {
setError(true);
});
}
firstUpdate.current = false;
},
[apiUrl]
);
return { data, error, callApi: setApiUrl };
};
import React from "react";
import { useDataApi } from "path/to/hoo/useDataApi.jsx";
import "whatwg-fetch";
import { renderHook } from "@testing-library/react-hooks";
import fetchMock from "fetch-mock";
import { act } from "react-test-renderer";
describe("useDataApi", () => {
beforeAll(() => {
global.fetch = fetch;
});
afterAll(() => {
fetchMock.restore();
});
it("should return data with a successful api request", async () => {
const { result } = renderHook(() => useDataApi());
// Tell the test that any request to 'test.com' should return 'returnedData: "foo"'
fetchMock.mock("test.com", {
returnedData: "foo"
});
// Calling the api via the `callApi` function
await act(async () => {
result.current.callApi("test.com");
});
// Check the 'data' state variable has the same mocked data from earlier
expect(result.current.data).toBe({
returnedData: "foo"
});
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.