Skip to content

Instantly share code, notes, and snippets.

@Drag13
Last active April 9, 2024 16:24
Show Gist options
  • Save Drag13/233c768e81900933a7ae7089f3166de1 to your computer and use it in GitHub Desktop.
Save Drag13/233c768e81900933a7ae7089f3166de1 to your computer and use it in GitHub Desktop.

Testing with context

Context

Create a context to wrap the fetch.

import { createContext, useContext } from "react";

const API = {
  getRandomFact(): Promise<string> {
    return fetch("https://api.chucknorris.io/jokes/random")
      .then((r) => r.json())
      .then((d) => d.value);
  },
};

export const ApiContext = createContext(API);

Component

Use context in a component instead of using the regular fetch

import { useContext, useEffect, useState } from "react";

export function RandomFact() {
  const { getRandomFact } = useContext(ApiContext);
  const [fact, setFact] = useState("");
  useEffect(() => {
    getRandomFact().then(setFact);
    return () => console.log("cancelling request");
  }, []);

  return <p> {fact}</p>;
}

Test

Test the code using fake API. Note that no network call will be done. This way we can wrap a code with any external activities

import { expect, test } from "vitest";
import { render, screen } from "@testing-library/react";
import { ApiContext, RandomFact } from "./random-fact";

test("On load random fact should be called", async () => {
  const fakeApi = { getRandomFact: () => Promise.resolve("fact") };

  render(
    <ApiContext.Provider value={fakeApi}>
      <RandomFact />
    </ApiContext.Provider>
  );

  const fact = await screen.findByText("fact");
  expect(fact).toBeInTheDocument();
});

Notes

This code requires extra setup:

vite-config.ts

import { defineConfig } from 'vitest/config';
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  test: {
    environment: "happy-dom",
    setupFiles: ["./vitest-setup.js"],
  },
});

And include vitest-setup.js into the tsconfig.json

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment