reactjs - TypeScript - 使用 Enzyme 调用 React 道具
问题描述
我正在尝试使用 Enzyme 将我的 Jest 测试转换为 TypeScript,但遇到了一种我不确定如何处理的特殊情况。基本上,我试图调用一个作为道具传递给子组件的函数。我看到的错误是:
规范/javascript/_common/components/sidebar_spec.tsx:85:5 - 错误 TS2349:
Cannot invoke an expression whose type lacks a call signature. Type '{}' has no compatible call signatures.
85 component.find(Link).at(0).prop('onNavigate')();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
我如何克服这个错误?不确定它是否有帮助,但测试的更多上下文:
it('does not hide the sidebar after a link is clicked', () => {
const component = shallow(<Sidebar />);
component.find(Link).at(0).prop('onNavigate')();
component.update();
expect(component.find(Link)).toHaveLength(3);
});
以及来自组件的一段代码Sidebar
:
class Sidebar extends React.Component<any, any> {
...
hideIfMobile() {
const {mobile} = this.state;
if (mobile) { this.setState({visible: false}); }
}
render() {
const {visible} = this.state;
if (!visible) {
return (
<div className='sidebar sidebar--hidden'>
{this.sidebarToggle()}
</div>
);
}
const linkProps = {
baseClass: 'sidebar__link',
onNavigate: this.hideIfMobile,
};
return (
<div className='sidebar sidebar--visible'>
<h2 className='sidebar__header'>{'Menu'}{this.sidebarToggle()}</h2>
<hr className='sidebar__divider' />
<Link to='root' {...linkProps}><h2>{'FOCUS'}</h2></Link>
<Link to='tasks' {...linkProps}><h2>{'ALL TASKS'}</h2></Link>
<Link to='timeframes' {...linkProps}><h2>{'TIMEFRAMES'}</h2></Link>
</div>
);
}
}
Link 组件包含在react-redux
:
import {connect} from 'react-redux';
import Link from 'src/route/components/link';
import {getRouteName} from 'src/route/selectors';
import {setRoute} from 'src/route/action_creators';
function mapStateToProps(state) {
return {routeName: getRouteName(state)};
}
export default connect(mapStateToProps, {setRoute})(Link);
和实际组件:
class Link extends React.Component<any, any> {
navigate(event) {
event.preventDefault();
const {onNavigate, params, setRoute, to} = this.props;
setRoute({name: to, ...params});
if (onNavigate) { onNavigate(); }
}
path() {
const {params, to} = this.props;
const pathParams = mapValues(params, value => value.toString());
return findRoute(to).toPath(pathParams);
}
className() {
const {baseClass, className, to, routeName} = this.props;
return classnames(
baseClass,
{[`${baseClass}--active`]: baseClass && routeName === to},
className,
);
}
render() {
const {children} = this.props;
return (
<a
href={this.path()}
className={this.className()}
onClick={this.navigate}
>
{children}
</a>
);
}
}
解决方案
事实证明,Link
在这种情况下,我的测试文件之前将其定义为:
const Link = 'Connect(Link)';
我将其切换为导入实际的链接容器,它解决了这个问题。
import Link from 'src/route/containers/link';
推荐阅读
- casbin - 如何基于多组成员身份使用 Casbin 保护资源
- postgresql - 如何通知 pod(s) 其他副本 pod 的 IP 地址
- python - 如何在另一个文件夹中导入 Python 模块,而无需相对导入和编辑 PYTHONPATH
- python - 如何将列表:numpy.int64 实例转换为 model.fit 的(稀疏/二进制)分类格式?
- javascript - Pug 多次打印相同的值
- node.js - 测试函数是否已运行的问题
- design-patterns - 我们如何实现有状态的访问者模式?
- api - 是否有任何静态代码分析工具来验证 API REST 指南?
- html - svg中线性渐变颜色的悬停事件
- javascript - 在容器内使用 fullpage.js