Skip to content

Instantly share code, notes, and snippets.

@jicking
Created June 3, 2023 03:32
Show Gist options
  • Select an option

  • Save jicking/7bc4ffd856035392f7e6c4f53dffc000 to your computer and use it in GitHub Desktop.

Select an option

Save jicking/7bc4ffd856035392f7e6c4f53dffc000 to your computer and use it in GitHub Desktop.
React test mocking DEMO
/* eslint-disable testing-library/prefer-screen-queries */
import { fireEvent, render } from "@testing-library/react";
import { AuthPanel } from "./AuthPanel";
import React from "react";
// Mock the useAuth hook
const useAuthMockReturnValue = { isAuthenticated: false, toogleAuthHanlder: jest.fn() };
const useAuthMock = jest.fn().mockReturnValue(useAuthMockReturnValue);
// jest.mock is hoisted above import when used at top level and hoisted to the the
// beginning of the block when used in a block (test function scope, etc), same
// for jest.unmock. jest.doMock and jest.dontMock serve the same purpose but aren't hoisted.
// https://stackoverflow.com/questions/64245013
// https://stackoverflow.com/questions/71432399
jest.mock("./useAuth", () => ({
useAuth: useAuthMock,
}));
describe("AuthPanel", () => {
// only use beforeEach for setup wrappers or dependencies EXCEPT for mocking
// https://stackoverflow.com/questions/57497799
it("should render login button when not authenticated", () => {
// Uses default useAuth mock
const { getByText } = render(<AuthPanel />);
const loginButton = getByText("login");
expect(loginButton).toBeInTheDocument();
});
it("should render logout button when authenticated", () => {
// Mock the return value of useAuth hook
useAuthMock.mockReturnValueOnce({ isAuthenticated: true, toogleAuthHanlder: jest.fn() });
const { getByText } = render(<AuthPanel />);
const logoutButton = getByText("logout");
expect(logoutButton).toBeInTheDocument();
});
it("should toggle authentication status on button click", () => {
// Create a mock toggleAuthHandler function
const toggleAuthHandler = jest.fn();
// Mock the return value of useAuth hook
useAuthMock.mockReturnValue({ isAuthenticated: false, toogleAuthHanlder: toggleAuthHandler });
const { getByText } = render(<AuthPanel />);
const loginButton = getByText("login");
fireEvent.click(loginButton);
expect(toggleAuthHandler).toHaveBeenCalled();
});
it('mock react useState', () => {
const setState = jest.fn();
jest
.spyOn(React, 'useState')
.mockImplementationOnce(() => [true, setState]);
});
});
import { useAuth } from "./useAuth";
export function AuthPanel() {
const { isAuthenticated, toogleAuthHanlder } = useAuth();
return (
<div>
{isAuthenticated ? (
<button onClick={toogleAuthHanlder}>logout</button>
) : (
<button onClick={toogleAuthHanlder}>login</button>
)}
</div>
);
}
import { renderHook, act } from "@testing-library/react-hooks";
import { useAuth } from "./useAuth";
describe("useAuth", () => {
it("should initialize with isAuthenticated set to false", () => {
const { result } = renderHook(() => useAuth());
expect(result.current.isAuthenticated).toBe(false);
});
it("should toggle the isAuthenticated state when calling toggleAuthHandler", () => {
const { result } = renderHook(() => useAuth());
expect(result.current.isAuthenticated).toBe(false);
act(() => {
result.current.toogleAuthHanlder();
});
expect(result.current.isAuthenticated).toBe(true);
act(() => {
result.current.toogleAuthHanlder();
});
expect(result.current.isAuthenticated).toBe(false);
});
});
import { useState } from "react";
export const useAuth = function () {
const [isAuthenticated, setAuthenticated] = useState(false);
const toogleAuthHanlder = () => setAuthenticated(!isAuthenticated);
return { isAuthenticated, toogleAuthHanlder };
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment