Vitest+Preact问题:添加forwardRef导致mock的setValue未触发
Preact组件添加forwardRef后测试用例失败问题
未使用forwardRef的组件测试通过
我有一个可正常运行的Preact组件和对应的Vitest测试用例,最简示例如下:
组件
import { ChangeEvent } from 'preact/compat'; export function DateInput({ value, setValue, label, }: { value: string; setValue: (value: string) => void; label: string; }) { const storeValue = (e: ChangeEvent): void => { // console.log('event fired'); --> 可触发 const elem: HTMLInputElement = e.currentTarget as HTMLInputElement; setValue(elem.value); }; return ( <> <label htmlFor="test-id">{label}</label> <input type="date" value={value} id="test-id" onChange={storeValue} /> </> ); }
测试用例(可通过)
it.only('should update state when date is changed', async () => { const setValue = vi.fn(); const { container } = render( <DateInput value={m.valueOutput1} // "2024-01-30" setValue={setValue} label={m.customLabel} // "Test label:" /> ); const htmlInput: HTMLInputElement | null = queryByLabelText( container as HTMLElement, m.customLabel ); if (htmlInput) { await act(() => { fireEvent.change(htmlInput, { target: { value: m.valueOutput2 } }); // "2024-01-31" }); await waitFor(() => { expect(setValue).toHaveBeenCalledOnce(); // 无forwardRef时通过,添加后失败 }); } });
添加forwardRef后测试用例失败
修改组件使用forwardRef后,测试用例失败,报错信息:
AssertionError: expected "spy" to be called once, but got 0 times
对应代码行:
201| await waitFor(() => { 202| expect(setValue).toHaveBeenCalledOnce(); | ^ 203| });
添加forwardRef后的组件
import { Ref } from 'preact'; import { ForwardedRef, forwardRef, ChangeEvent } from 'preact/compat'; export const DateInput = forwardRef(function DateInput( { value, setValue, label, }: { value: string; setValue: (value: string) => void; label: string; }, ref: ForwardedRef<HTMLElement> ) { const storeValue = (e: ChangeEvent): void => { // console.log('event fired'); --> 不再触发 const elem: HTMLInputElement = e.currentTarget as HTMLInputElement; setValue(elem.value); }; return ( <> <label htmlFor="test-id">{label}</label> <input type="date" value={value} id="test-id" onChange={storeValue} ref={ref as Ref<HTMLInputElement>} /> </> ); });
已尝试的解决方法
- 搜索4小时未找到完全匹配的问题
- 测试中使用/不使用async函数(act和waitFor)均无效果
- 验证测试步骤执行顺序与代码一致
- 为测试组件添加React.createRef()也无法解决
- 调试发现使用forwardRef时onChange事件完全未触发,断点仅能打到input标签处,无法进入事件回调
内容的提问来源于stack exchange,提问作者Xzsh4s575sf75
相关产品推荐
相关产品推荐

