Skip to content

Instantly share code, notes, and snippets.

@andrecalvo
Last active March 11, 2022 12:22
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andrecalvo/b4fa0390efec6212cd464111e7f6272a to your computer and use it in GitHub Desktop.
Save andrecalvo/b4fa0390efec6212cd464111e7f6272a to your computer and use it in GitHub Desktop.
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