when i use react-testing-library, it says that error: invariant expected app router to be mounted , it has no such problem when running in the development environment.
the testing logics is here
import { render, screen } from "@testing-library/react"
import userEvent from "@testing-library/user-event"
import NavBar from "@/components/NavBar";
describe("<NavBar>", () => {
it ("the login pop out displayed after click the login/sign up button", async () => {
render(<NavBar />);
const loginButton = screen.getByRole("link", {
name: "LOGIN/SIGN UP"
});
const loginCard = screen.getByTestId("loginCard");
await userEvent.click(loginButton);
expect(loginButton).toBeCalled();
expect(loginCard).toBeVisible();
})
});
the components is here: Navbar:
"use client"
import React, { Dispatch, SetStateAction } from "react";
import { useRouter } from "next/navigation";
interface NavBarProps {
setVisibleLogin?: Dispatch<SetStateAction<boolean>>;
}
const NavBar = ({ setVisibleLogin }: NavBarProps) => {
const router = useRouter();
const handleLoginBtn = () => {
setVisibleLogin && setVisibleLogin(true);
};
const handleHome = () => {
router.push("/");
};
return (
<div className="bg-slate-50 flex justify-center">
<div className="fix w-912px top-0 navbar w-require">
<div className="navbar-start">
<a
className="btn btn-ghost normal-case text-xl text-sky-500"
onClick={handleHome}
>
Alimama MealGPT
</a>
</div>
<div className="navbar-center hidden lg:flex"></div>
{
// for distinguish between the page for login and others
setVisibleLogin && (
<div className="navbar-end">
<a className="btn" onClick={handleLoginBtn}>
Login/Sign Up
</a>
</div>
)
}
</div>
</div>
);
};
export default NavBar;
LoginCard:
"use client"
import React, { Dispatch, SetStateAction } from "react";
import InputBox from "./InputBox";
import Image from "next/image";
import { useRouter } from "next/navigation";
import GoogleLoginCard from "@/assets/[email protected]"
interface LoginCardProps {
visibleLogin: boolean;
setVisibleLogin: Dispatch<SetStateAction<boolean>>;
}
const LoginCard = ({visibleLogin, setVisibleLogin}: LoginCardProps) => {
const router = useRouter();
const handleCancel = () => {
setVisibleLogin(false);
}
const handleSignUp = () => {
router.push("/SignUp");
}
return (
<div
className="fixed left-1/2 top-1/2 -translate-x-2/4 -translate-y-2/4 z-50"
style={{ visibility: visibleLogin ? "visible" : "hidden" }}>
<div className="card w-96 bg-neutral text-neutral-content bg-slate-200">
<div className="flex flex-row-reverse">
<div className="flex flex-row-reverse" style={
{
position: "relative",
top: "0.5rem",
right: "0.5rem"
}
}>
<button className="btn btn-outline w-2 h-2" onClick={handleCancel}>X</button>
</div>
<a className="relative right-10 top-3 btn btn-ghost normal-case text-xl text-sky-500">Alimama MealGPT</a>
</div>
<div className="card-body items-center text-center">
<h2 className="card-title">Login</h2>
<InputBox
title="Email/ User ID"
textHolder="Please Enter Your Email or ID Here"
otherLeftOption={false}
otherRightOption={false}
/>
<InputBox
title="Password"
textHolder="Please Enter Your Password Here"
otherLeftOption={true}
otherRightOption={true}
optionLeftText="Forget Password?"
optionRightText="Any Other Helps?"
/>
<div className="card-actions justify-end">
<button className="btn btn-primary w-27">Log In</button>
<button className="btn btn-primary w-25" onClick={handleSignUp}>Sign Up</button>
<button className="btn btn-outline" onClick={handleCancel}>Cancel</button>
</div>
<div>
<Image src={GoogleLoginCard}
height={200}
width={200}
alt="google login button"
/>
</div>
</div>
</div>
</div>
);
};
export default LoginCard;
I saw some other similar question have such solution like add the html head and body tag on layout.tsx, i put head and body tag in layout.tsx already.
Does anyone know how to fix this problem?
I expect the solusion for fix the problem.
For me it worked to mock useRouter in the Jest test like this:
imports ...
// Mock useRouter:
jest.mock("next/navigation", () => ({
useRouter() {
return {
prefetch: () => null
};
}
}));
describe("Test something", () => { ...
The idea was taken from here (I just changed "next/router" to "next/navigation").
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