I'm using React(react-create-app and TypeScript). Login is made with Auth0.
I want to write tests with Jest, and I found this ressource which is basically the only thing around that speaks about Mocking the Auth0 object.
So my code looks like this:
import React from "react";
import ReactDOM from "react-dom";
import TopBar from "./index";
import {
useAuth0
} from "react-auth0-spa";
const user = {
email: "[email protected]",
email_verified: true,
sub: "google-oauth2|12345678901234"
};
// intercept the useAuth0 function and mock it
jest.mock("react-auth0-spa");
describe("First test", () => {
beforeEach(() => {
// Mock the Auth0 hook and make it return a logged in state
useAuth0.mockReturnValue({
isAuthenticated: true,
user,
logout: jest.fn(),
loginWithRedirect: jest.fn()
});
});
it("renders without crashing", () => {
const div = document.createElement("div");
ReactDOM.render( < TopBar / > , div);
});
});
But I end stuck with this error:
Property 'mockReturnValue' does not exist on type '() => IAuth0Context | undefined'.ts(2339)
I'm a bit lost here, any help would be greatly appreciated!
Default Export To mock a React component, the most straightforward approach is to use the jest. mock function. You mock the file that exports the component and replace it with a custom implementation. Since a component is basically a function, the mock should also return a function.
Note: In order to mock properly, Jest needs jest. mock('moduleName') to be in the same scope as the require/import statement. Here's a contrived example where we have a module that provides a summary of all the files in a given directory. In this case, we use the core (built in) fs module.
Spent an hour or so figuring this out myself. Problem stems from incorrect types being applied to useAuth0 after modifying mock return value. My solution was to use mocked from 'ts-jest/utils'. You can add Roles, Scope etc to user object also. (see adminUser object)
import { render, screen } from "@testing-library/react";
import { useAuth0 } from "@auth0/auth0-react";
import { mocked } from "ts-jest/utils";
const user = {
email: "[email protected]",
email_verified: true,
sub: "google-oauth2|12345678901234",
};
const adminUser = {
email: "[email protected]",
email_verified: true,
sub: "google-oauth2|12345678901234",
"https://<<API_URL>>/roles": ["admin", "superuser"],
};
jest.mock("@auth0/auth0-react");
const mockedUseAuth0 = mocked(useAuth0, true);
describe("TopNav Component Tests - Logged in", () => {
beforeEach(() => {
mockedUseAuth0.mockReturnValue({
isAuthenticated: true,
user,
logout: jest.fn(),
loginWithRedirect: jest.fn(),
getAccessTokenWithPopup: jest.fn(),
getAccessTokenSilently: jest.fn(),
getIdTokenClaims: jest.fn(),
loginWithPopup: jest.fn(),
isLoading: false,
});
});
test("Logout Button displays when logged in", () => {
render(
<TopNav />
);
const loginButton = screen.getByText(/Logout/i);
expect(loginButton).toBeInTheDocument();
});
test("Make sure Admin Panel Button doesnt show without Role", () => {
render(
<TopNav />
);
const adminPanelButton = screen.queryByText(/Admin Panel/i);
expect(adminPanelButton).toBeNull();
});
});
describe("TopNav Component Tests - Admin User", () => {
beforeEach(() => {
mockedUseAuth0.mockReturnValue({
isAuthenticated: true,
user: adminUser,
logout: jest.fn(),
loginWithRedirect: jest.fn(),
getAccessTokenWithPopup: jest.fn(),
getAccessTokenSilently: jest.fn(),
getIdTokenClaims: jest.fn(),
loginWithPopup: jest.fn(),
isLoading: false,
});
});
test("Admin Panel Button displays", () => {
render(
<TopNav />
);
const adminPanelButton = screen.getByText(/Admin Panel/i);
expect(adminPanelButton).toBeInTheDocument();
});
});
It's a TypeScript error. You will need to type the mocked useAuth0
as the original type does not have a method called mockReturnValue
. Something like this should work:
const mockedUseAuth0 = <jest.Mock<typeof useAuth0>>useAuth0;
mockedUseAuth0.mockReturnValue({
isAuthenticated: true,
user,
logout: jest.fn(),
loginWithRedirect: jest.fn()
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With