我正在尝试在 cypress 中测试我的组件。该组件使用按钮中的 next/navigation 中的 useRouter 钩子推回到另一个页面。
import { useRouter } from "next/navigation";
import { VStack, Heading, Text, Button, Box, HStack } from "@chakra-ui/react";
const ForgotPassword = () => {
const [usersEmails, setUsersEmails] = useState<String[]>([]);
const [email, setEmail] = useState("");
const [error, setError] = useState(false);
const router = useRouter()
useEffect(() => {
const fetchEmails = async () => {
const { error, data } = await supabase.from("users").select("email");
if (error) {
console.log(error);
} else {
const emailArray = data.map((user) => user.email);
setUsersEmails(emailArray);
}
};
fetchEmails();
}, [supabase]);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
};
return (
<HStack h="100vh">
<Box>
<VStack w="full" maxW="md">
<Heading as="h3" size="lg" color="#006bb2" alignSelf="flex-start">
Forgot Password
</Heading>
<Text mb="15px">
Enter your email and we"ll send a link to reset your password
</Text>
<form onSubmit={handleSubmit}>
<input
type="email"
id="email"
name="email"
placeholder="[email protected]"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
{error && (
<Text mt="5px" color="red">
We cannot find your email
</Text>
)}
<button>
Submit
</button>
</form>
<Button
leftIcon={<ArrowBackIcon />}
color="gray.500"
_hover={{ color: "#006bb2", cursor: "pointer" }}
variant="link"
onClick={() => router.push("/login")}
>
Back to Login
</Button>
</VStack>
</Box>
</HStack>
);
};
export default ForgotPassword;
当我安装组件时,我收到来自 cypress 的错误
(未捕获的异常)错误:要安装不变的预期应用程序路由器
以下错误源自您的应用程序代码,而不是来自赛普拉斯。 不变的预期应用程序路由器将被安装
但是如果我注释掉“import useRouter”、“const router = useRouter()”行并删除“router.push("/login")”,那么组件就会挂载并且cypress不会抛出任何错误
我已经尝试过来自 cypress 文档的下一个/路由器和下一个/链接解决方案
import React from 'react'
import ForgotPassword from './page'
import Router from 'next/router'
describe('Testing the forgot password component', () => {
context('stubbing out `useRouter` hook', () => {
let router
beforeEach(() => {
router = {
push: cy.stub().as('router:push')
}
cy.stub(Router, 'useRouter').returns(router)
})
it('checks if user email exits in db', () => {
cy.mount(<ForgotPassword />)
cy.get('input[name="email"]').type("[email protected]");
// cy.get('button').click()
// cy.get('@routerBack').should((mock) => {
// expect(mock).to.have.been.calledOnce
// })
})
})
})
cypress 仍然抛出相同的“(未捕获异常)错误:不变的预期应用程序路由器要安装”错误,并且组件仍然无法安装。
我将行
import Router from 'next/router'
更改为 import Router from 'next/navigation'
并且 cypress 错误更改为
尝试存根未定义的属性“useRouter”
因为这个错误发生在每个钩子之前,我们将跳过当前套件中的剩余测试:删除 useRouter 钩子
未捕获的异常
Error: invariant expected app router to be mounted
可以通过将组件包装在<AppRouterContext.Provider value={router}>
中来解决。
这是主要的修复,但还有一些次要的修复:
测试中使用
'next/router'
,但组件中使用"next/navigation"
。两个地方的路由器应该是相同的。
要从
useRouter
对象存根 Router
,您需要使用 import * as Router from "next/navigation"
import Router from "next/navigation"
Trying to stub property 'useRouter' of undefined
断言中使用的别名应与存根中使用的名称相同。
calledOnce
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}