我正在尝试测试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)
任何帮助将不胜感激,因为现在已经两天了,我不知道这一点。
答案 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。
是的,确切地说-如果发生任何更改,必须从根目录重新找到所有内容。