是否可以断言一个函数是否为空函数?

时间:2018-08-04 23:25:47

标签: reactjs jestjs

我有一个像这样的通用输入组件:

class GenericInputComponent extends React.Component {
   constructor (props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange (evt) {
    this.props.onChange(evt);
  }

  render () {
    return (<Something />)
  }
}

GenericComponent.defaultProps = {
  onChange: () => {}
}

对于此组件,我的测试之一是测试组件是否使用默认道具:

it('should use default props', function () {
   delete props.onChange // Before this the onChange was jest.fn()

   rendered.unmount()

   rendered = shallow(<Input {...props} />)

   let onChange = () => {}

   expect(rendered.instance().props.onChange).toEqual(onChange)
   expect(rendered.instance().props.onChange).toBeInstanceOf(Function)  
})

测试在以下行失败:

expect(rendered.instance().props.onChange).toEqual(onChange)

并给出此错误:

Expected value to equal:
      [Function onChange]
    Received:
      [Function onChange]

    Difference:

    Compared values have no visual difference.

从我的角度来看,它应该过去了,但事实并非如此。为什么?可以断言所使用的函数是否为空函数?

此外,如果我尝试监视这样的功能:

let onChangeSpy = jest.spyOn(rendered.instance().props, 'onChange')

我收到此错误:

`TypeError: Cannot assign to read only property 'onChange' of object '[object Object]'`

仅供参考,我正在使用shallow渲染进行测试。

那么可以对空函数进行断言吗?另外,这是唯一coverage不能覆盖100%的情况。

2 个答案:

答案 0 :(得分:0)

两个onChange变量具有相同的名称,但是引用了不同的函数,导致相等性检查失败。您需要从组件中导出默认的onChange函数,并将其导入测试中以执行断言。

GenericComponent.js

class GenericComponent extends React.Component {
   constructor (props) {
    super(props);

    this.handleChange = this.handleChange.bind(this);
  }

  handleChange (evt) {
    this.props.onChange(evt);
  }

  render () {
    return (<Something />)
  }
}

export const onChange = () => {}

GenericComponent.defaultProps = {
  onChange
}

GenericComponent.test.js

import {onChange} from '../GenericComponent.js';

it('should use default props', function () {
   delete props.onChange // Before this the onChange was jest.fn()

   rendered.unmount()

   rendered = shallow(<Input {...props} />)

   expect(rendered.instance().props.onChange).toEqual(onChange)
   expect(rendered.instance().props.onChange).toBeInstanceOf(Function)  
})

我同意这可能对测试并不重要,而只是想说明引用相等性。

答案 1 :(得分:0)

这是可以预期的,因为函数是对象,并且对象通过JavaScript中的引用进行比较:

(() => {}) !== (() => {})

可以通过断言onChange.toString()来测试该方法是否为空。但是这里应该测试的是onChange不仅是一个空函数,而且是默认设置的prop。即应该是:

expect(rendered.instance().props.onChange).toBe(GenericInputComponent.defaultProps.onChange)

如果该函数为空,则可以选择对其进行测试:

expect(GenericInputComponent.defaultProps.onChange).toBeInstanceOf(Function);
expect(GenericInputComponent.defaultProps.onChange.toString().match(/\{(.*)}$/)[1])).toMatch(/^\s*$/);