reactjs - 如何使用 Typescript 将 jest.spyOn 与 React 函数组件一起使用
问题描述
我正在使用 Typescript 和 hooks 开发一个 React 应用程序,并且我正在尝试使用 Enzyme 和 Jest 来测试功能组件。我无法使用 jest.spyOn 来测试我的组件中的方法。jest.spyOn 方法无法正确解析并在悬停时显示以下消息
““validateBeforeSave”类型的参数不能分配给“context”|“setState”|“forceUpdate”|“render”|“componentDidMount”|“shouldComponentUpdate”|“componentWillUnmount”|“componentDidCatch”|“ getSnapshotBeforeUpdate" | ... 6 更多 ... | "UNSAFE_componentWillUpdate"'.ts(2345)"
我试图将实例转换为“任何”-
const instance = wrapper.instance() as any;
这当然忽略了编译时的问题,但是测试会抛出一个运行时错误,即组件上不存在函数。
无法窥探 validateBeforeSave 属性,因为它不是函数;给定的未定义
// Some function Component
const SomeComponent = (props: IMyComponentProps) => {
const { classes } = props;
// Component has state
const [count, setCount] = useState(0);
function validateBeforeSave(){
}
function handleClick() {
validateBeforeSave();
.
.
.
}
return (
<div>
<Button>
className="saveBtn"
onClick={handleClick}
</Button>
</div>
);
};
// Unit test
describe('SomeComponent' () => {
it('validates model on button click', () => {
const wrapper = mount(
<MuiThemeProvider theme={theme}>
<SomeComponent/>
</MuiThemeProvider>,
);
const instance = wrapper.instance();
const spy = jest.spyOn(instance, "validateBeforeSave");
wrapper
.find('.saveBtn')
.at(0)
.simulate('click');
expect(spy).toHaveBeenCalledTimes(1);
});
}
我在这里想念什么?spyOn 如何与函数组件一起工作?
我使用 create-react-app 模板创建了应用程序,它具有测试包的这些依赖项
"devDependencies": {
"ts-jest": "^23.10.3",
"@types/jest": "24.0.9",
"@types/enzyme": "^3.9.1",
"@types/enzyme-adapter-react-16": "^1.0.2",
"enzyme": "^3.9.0",
"enzyme-adapter-react-16": "^1.11.2",
"enzyme-to-json": "^3.3.5",
}
解决方案
您的validateBeforeSave
函数在内部声明,SomeComponent
使其成为外部无法访问的封闭/私有范围函数。您可以将该函数作为道具传递,然后您可以创建间谍并将其作为道具值在您的测试中传递,并测试传递的道具函数(间谍)是否被调用
所以你会修改你的函数有点像这样:
// some validator function
function validateBeforeSave(){
...
}
// Some function Component
const SomeComponent = (props: IMyComponentProps) => {
const { classes, validateBeforeSave } = props;
// Component has state
const [count, setCount] = useState(0);
function handleClick() {
validateBeforeSave();
.
.
.
}
return (
<div>
<Button>
className="saveBtn"
onClick={handleClick}
</Button>
</div>
);
};
在你的单元测试中,像这样:
// Unit test
describe('SomeComponent' () => {
it('validates model on button click', () => {
const validateSpy = jest.fn();
const wrapper = mount(
<MuiThemeProvider theme={theme}>
<SomeComponent validateSpy={validateSpy}/>
</MuiThemeProvider>,
);
const instance = wrapper.instance();
wrapper
.find('.saveBtn')
.at(0)
.simulate('click');
expect(validateSpy).toHaveBeenCalledTimes(1);
});
}
推荐阅读
- android - 是否可以创建一个 ios/android 应用程序来限制用户在一段时间内使用应用程序或网站
- php - 使用引导 v4 重定向到 laravel 中的特定选项卡
- javascript - 动态添加帖子数据以稍后使用表单提交
- list - OCaml 中的列表匹配
- c - 使用指针将二维数组传递给 C 中的函数
- javascript - 获取打开模式的按钮(不带有 data-* html 标签)
- c++ - 如何在使用 cin 请求 int 时有效地防止用户输入?
- angular - 在 Angular6 服务未加载
- java - 如何确保使用 BufferedWriter 及时输出到文件?
- sql - SQL Server 中所有联合的 Row_number 函数