【发布时间】:2019-10-11 16:38:06
【问题描述】:
我正在尝试测试 RFC 上输入的 onChange 属性(和值)。在测试中,尝试模拟事件不会触发 jest mock 函数。
实际组件已连接(使用 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)
任何帮助将不胜感激,因为它已经 2 天了,我不知道这一点。
【问题讨论】:
-
getUserInputRequest在handleKeyUp内部被调用,当你执行input.props().onChange({ target: { value: userInput } })时它会调用handleChange,而不是handleKeyUp -
是的,没错。变量的命名约定错误。仍然不影响结果,因为我实际上想测试
handleChange。将更新以避免任何混淆。谢谢 -
在您的测试中,您将属性
handleChange传递给组件UnconnectedSearchInput。注意UnconnectedSearchInput不使用属性handleChange,所以这个属性永远不会被调用是正常的 -
等等,我很困惑。我将模拟作为
handleChange传递给UnconnectedSearchInput,它在实际组件的onChange={handleChange}上的input元素上被调用。我在这里错过了什么? -
当您编写
onChange={handleChange}时,它会检索您在const handleChange = (e: InputVal): void => { setChange(e.target.value) }之前声明的handleChange函数,而不是来自 props 的函数