TypeScript-使用酶调用React prop

时间:2018-08-30 03:52:57

标签: reactjs typescript jestjs enzyme

我正在尝试将使用酶的Jest测试转换为TypeScript,但是遇到一种我不确定如何处理的特殊情况。基本上,我正在尝试调用作为道具传递给子组件的函数。我看到的错误是:

spec / 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>
    );
  }
}

链接组件包装在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>
    );
  }
}

1 个答案:

答案 0 :(得分:0)

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

const Link = 'Connect(Link)';

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

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