首页 > 解决方案 > 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>
    );
  }
}

标签: reactjstypescriptjestjsenzyme

解决方案


事实证明,Link在这种情况下,我的测试文件之前将其定义为:

const Link = 'Connect(Link)';

我将其切换为导入实际的链接容器,它解决了这个问题。

import Link from 'src/route/containers/link';

推荐阅读