Javascript 在react钩子上调用时,jest.spyOn()TypeError
我试图在测试中使用Javascript 在react钩子上调用时,jest.spyOn()TypeError,javascript,reactjs,typescript,react-hooks,react-testing-library,Javascript,Reactjs,Typescript,React Hooks,React Testing Library,我试图在测试中使用jest.spyOn(),而不是jest.mock,因为mock的返回值不能进行类型检查。但当我使用它时,会出现以下错误: TypeError: Cannot set property useGame of #<Object> which has only a getter > 3 | const STATE_SPY = jest.spyOn(hooks, "useGame"); | ^
jest.spyOn()
,而不是jest.mock
,因为mock的返回值不能进行类型检查。但当我使用它时,会出现以下错误:
TypeError: Cannot set property useGame of #<Object> which has only a getter
> 3 | const STATE_SPY = jest.spyOn(hooks, "useGame");
| ^
at ModuleMockerClass.spyOn (node_modules/jest-mock/build/index.js:852:26)
at Object.<anonymous> (src/components/game/game.test.tsx:4:24)
下面是我的代码的布局(我为这个问题删除了很多无关的代码)
使其更易于阅读)
/hooks/index.tsx
:
export { default as useGame } from "./use-game";
export default function useGame(initScore: number) {
const [score, setScore] = useState(initScore);
return {
score,
setScore,
}
}
import * as hooks from "./hooks";
const STATE_SPY = jest.spyOn(hooks, "useGame");
import React from "react";
import { useGame } from "./hooks";
const STARTING_SCORE = 50;
export default function Game(): JSX.Element {
const {score} = useGame(STARTING_SCORE);
return (
<div>
{score}
</div>
)
}
使用game.tsx
:
export { default as useGame } from "./use-game";
export default function useGame(initScore: number) {
const [score, setScore] = useState(initScore);
return {
score,
setScore,
}
}
import * as hooks from "./hooks";
const STATE_SPY = jest.spyOn(hooks, "useGame");
import React from "react";
import { useGame } from "./hooks";
const STARTING_SCORE = 50;
export default function Game(): JSX.Element {
const {score} = useGame(STARTING_SCORE);
return (
<div>
{score}
</div>
)
}
game.test.tsx
:
export { default as useGame } from "./use-game";
export default function useGame(initScore: number) {
const [score, setScore] = useState(initScore);
return {
score,
setScore,
}
}
import * as hooks from "./hooks";
const STATE_SPY = jest.spyOn(hooks, "useGame");
import React from "react";
import { useGame } from "./hooks";
const STARTING_SCORE = 50;
export default function Game(): JSX.Element {
const {score} = useGame(STARTING_SCORE);
return (
<div>
{score}
</div>
)
}
game.tsx
:
export { default as useGame } from "./use-game";
export default function useGame(initScore: number) {
const [score, setScore] = useState(initScore);
return {
score,
setScore,
}
}
import * as hooks from "./hooks";
const STATE_SPY = jest.spyOn(hooks, "useGame");
import React from "react";
import { useGame } from "./hooks";
const STARTING_SCORE = 50;
export default function Game(): JSX.Element {
const {score} = useGame(STARTING_SCORE);
return (
<div>
{score}
</div>
)
}
我查看了your package.json,发现包
@testing library/react hooks
已经在前面添加了。我建议使用它来编写钩子的新测试
您可以阅读文档开始我查看了your package.json,发现包
@testing library/react hooks
已在前面添加。我建议使用它来编写钩子的新测试
您可以阅读文档开始似乎您使用babel来传输代码。正如我所知,如果您使用通配符(名称空间)这样导入。它将创建一个对象,其中包含命名为getter-like的导出
var obj={get namedExport:()=>…}
因此,在这种情况下,我建议模拟整个模块:
jest.mock('./hooks',()=>({useGame:yourMock}))
或者切换到
tsc
,使用ts jest
修复您的问题(因为tsc
不会使用getter导出指定的导出)似乎您使用babel来传输您的代码。正如我所知,如果您使用通配符(名称空间)这样导入。它将创建一个对象,其中包含命名为getter-like的导出
var obj={get namedExport:()=>…}
因此,在这种情况下,我建议模拟整个模块:
jest.mock('./hooks',()=>({useGame:yourMock}))
或者通过使用
ts jest
切换到tsc
来解决您的问题(因为tsc
不会使用getter导出指定的导出)除非我弄错了,这是为了测试钩子本身。我已经为钩子本身编写了测试(因为它不相关,所以没有包含在我的问题中)。我想做的是在测试组件函数的同时监视钩子,看看单击按钮是否会导致钩子状态的改变。除非我弄错了,否则这是为了测试钩子本身。我已经为钩子本身编写了测试(因为它不相关,所以没有包含在我的问题中)。我想做的是在测试组件函数时监视钩子,看看单击按钮是否会导致钩子状态的更改。我想避免模拟,因为模拟的返回值不能进行类型检查。我安装了ts jest
(24.3.0)并运行了npx ts jest-config:init
。但是当我运行npm测试时,我得到了完全相同的错误。记录hooks
会给出{useGame:[Getter]}
和hooks。useGame
以[Function:useGame]
的形式记录,找到了一个有效的解决方案。将其改写为:import*as useGame from.“/hooks/use game”代码>const STATE\u SPY=jest.spyOn(使用游戏,“默认”)
useGame
记录为{default:[函数:useGame]}
当这起作用时,对于样式点,我更喜欢从由index.tsx
创建的模块导入的解决方案,因为这是导入其他所有内容的方式。我希望避免模拟,因为无法检查模拟的返回值。我安装了ts jest
(24.3.0)并运行了npx ts jest-config:init
。但是当我运行npm测试时,我得到了完全相同的错误。记录hooks
会给出{useGame:[Getter]}
和hooks。useGame
以[Function:useGame]
的形式记录,找到了一个有效的解决方案。将其改写为:import*as useGame from.“/hooks/use game”代码>const STATE\u SPY=jest.spyOn(使用游戏,“默认”)
useGame
记录为{default:[函数:useGame]}
当这起作用时,对于样式点,我更喜欢从由index.tsx
创建的模块导入的解决方案,因为其他所有内容都是这样导入的。