Reputation: 11
I have a component in my reactjs project. The code is given below -
import jwt_decode from "jwt-decode";
import { createContext, useEffect, useState } from "react";
export const AuthContext = createContext();
export const AuthProvider = (props) => {
const [isLoggedIn, setIsLoggedIn] = useState(
localStorage.getItem("isLoggedIn") === "true"
);
const [browserCookie, setBrowserCookie] = useState(document.cookie);
useEffect(() => {
try {
jwt_decode(document.cookie);
} catch (error) {
setIsLoggedIn(false);
return;
}
}, [browserCookie]);
useEffect(() => {
localStorage.setItem("isLoggedIn", isLoggedIn);
}, [isLoggedIn]);
return (
<AuthContext.Provider value={{ isLoggedIn, setIsLoggedIn, browserCookie, setBrowserCookie }}>
{props.children}
</AuthContext.Provider>
);
};
I am trying to write unit tests for this code using vitest and react-testing-library. I have written the following code for testing -
import React from "react";
import { vi } from 'vitest';
import jwt_decode from "jwt-decode";
import { render, screen } from "@testing-library/react";
import { AuthProvider } from "../contexts/authContext";
describe("AuthProvider", () => {
test("renders children without errors", () => {
render(
<AuthProvider>
<div>Test Child</div>
</AuthProvider>
);
const childElement = screen.getByText("Test Child");
expect(childElement).toBeInTheDocument();
});
test('sets isLoggedIn to false if cookie decoding fails', () => {
vi.spyOn(jwt_decode).mockImplementation(() => {
throw new Error("Decoding error");
});
const useEffectSpy = vi.spyOn(AuthProvider, "useEffect");
useEffectSpy.mockImplementation(() => {
throw new Error("Decoding error");
});
render(
<AuthProvider>
<div>Test Child</div>
</AuthProvider>
);
expect(screen.queryByText('Test Child')).not.toBeInTheDocument();
});
});
But I am getting an error for the second test because I think I am not mocking the jwt_decode() function properly. The error is given below -
Error: undefined does not exist
❯ src/__tests__/authContext.test.jsx:22:8
20| test('sets isLoggedIn to false if cookie decoding fails', () => {
21|
22| vi.spyOn(jwt_decode).mockImplementation(() => {
| ^
23| throw new Error("Decoding error");
24| });
Can anyone please help me with the correct test code that mocks the function properly?
Upvotes: 1
Views: 4126
Reputation: 678
vitest.spyOn
takes two arguments: the object on which you want to insert a spy, and the name of the method you're spying on. In this situation, you're not calling a method on an object, as jwt_decode is a default export.
My recommendation would be to mock the module, like so:
import jwt_decode from "jwt_decode";
vi.mock("jwt_decode");
test('...', () => {
// If using TS:
vi.mocked(jwt_decode).mockImplementation(...);
// If using pure JS:
jwt_decode.mockImplementation(...);
});
Upvotes: 0