Jest /酶浅测试RFC-不触发jest.fn()

时间:2019-05-25 09:15:23

标签: reactjs jestjs enzyme

我正在尝试测试RFC上输入的onChange属性(和值)。在测试中,尝试模拟事件不会触发开玩笑的模拟功能。

实际的组件已连接(使用redux),但我也将其导出为未连接的组件,因此可以进行浅层单元测试。我还在动画中使用了一些react-spring钩子。

我也尝试安装组件而不是将组件变浅,但仍然遇到相同的问题。


我的组件



export const UnconnectedSearchInput: React.FC<INT.IInputProps> = ({ scrolled, getUserInputRequest }): JSX.Element => {

  const [change, setChange] = useState<string>('')


  const handleChange = (e: InputVal): void => {
    setChange(e.target.value)
  }

  const handleKeyUp = (): void => {
    getUserInputRequest(change)
  }

  return (
    <animated.div
      className="search-input"
      data-test="component-search-input"
      style={animateInputContainer}>

      <animated.input
        type="text"
        name="search"
        className="search-input__inp"
        data-test="search-input"
        style={animateInput}
        onChange={handleChange}
        onKeyUp={handleKeyUp}
        value={change}
      />
    </animated.div>
  )
}


export default connect(null, { getUserInputRequest })(UnconnectedSearchInput); 



我的测试

在这里您可以看到测试失败。到目前为止,我已尝试过注释掉代码的其他事情,但是没有任何运气。



describe('test input and dispatch action', () => {
  let changeValueMock
  let wrapper
  const userInput = 'matrix'

  beforeEach(() => {
    changeValueMock = jest.fn()
    const props = {
      handleChange: changeValueMock
    }

    wrapper = shallow(<UnconnectedSearchInput {...props} />).dive()
    // wrapper = mount(<UnconnectedSearchInput {...props} />)
  })

  test('should update input value', () => {
    const input = findByTestAttr(wrapper, 'search-input').dive()
    // const component = findByTestAttr(wrapper, 'search-input').last()

    expect(input.name()).toBe('input')
    expect(changeValueMock).not.toHaveBeenCalled()

    input.props().onChange({ target: { value: userInput } }) // not geting called
    // input.simulate('change', { target: { value: userInput } })

    // used with mount
    // act(() => {
    //   input.props().onChange({ target: { value: userInput } })
    // })
    // wrapper.update()

    expect(changeValueMock).toBeCalledTimes(1)

    // expect(input.prop('value')).toBe(userInput);
  })
})


测试错误

这里没什么特别的。

 expect(jest.fn()).toBeCalledTimes(1)

    Expected mock function to have been called one time, but it was called zero times.

      71 |     // wrapper.update()
      72 | 
    > 73 |     expect(changeValueMock).toBeCalledTimes(1)

任何帮助将不胜感激,因为现在已经两天了,我不知道这一点。

1 个答案:

答案 0 :(得分:2)

您不必与组件内部进行交互;相反,最好使用公共接口:道具和渲染结果

test('should update input value', () => {
  expect(findByTestAttr(wrapper, 'search-input').dive().props().value).toEqual('');
  findByTestAttr(wrapper, 'search-input').dive().props().onChange({ target: {value: '_test_'} });
  expect(findByTestAttr(wrapper, 'search-input').dive().props().value).toEqual('_test_');
}

看到您不需要检查是否已调用某些内部方法,其名称或参数是什么。如果您得到了所需的东西,并且需要将<input>与预期的value相结合,那么事情如何发生也没关系。

但是,如果函数是从外部(通过props传递的,则您肯定希望验证是否在某些预期情况下调用了该函数

test('should call getUserInputRequest prop on keyUp event', () => {
  const getUserInputRequest = jest.fn();
  const mockedEvent = { target: { key: 'A' } };
  const = wrapper = shallow(<UnconnectedSearchInput getUserInputRequest={getUserInputRequest } />).dive()
  findByTestAttr(wrapper, 'search-input').dive().props().onKeyUp(mockedEvent)
  expect(getUserInputRequest).toHaveBeenCalledTimes(1);
  expect(getUserInputRequest).toHaveBeenCalledWith(mockedEvent);
}

[UPD]似乎像interm变量一样缓存选择器

const input = findByTestAttr(wrapper, 'search-input').dive();
input.props().onChange({ target: {value: '_test_'} });
expect(input.props().value).toEqual('_test_');

不通过,因为input指的是value不更新的陈旧对象。

在酶的github上,我been answered是预期的行为:

  

这是酶v3中的预期行为-参见https://github.com/airbnb/enzyme/blob/master/docs/guides/migration-from-2-to-3.md#calling-props-after-a-state-change

     

是的,确切地说-如果发生任何更改,必须从根目录重新找到所有内容。