如何用React Testing Library测试react-select菜单滚动到底部事件
要触发onMenuScrollToBottom,你需要定位到react-select的下拉菜单容器(而非外层select元素),再模拟滚动到底部的行为——因为onMenuScrollToBottom是监听菜单容器的滚动事件,而非你点击的外层select元素。
具体修改步骤:
- 打开菜单后定位下拉容器:react-select的下拉菜单会渲染为带
role="listbox"的元素,用这个角色定位最稳定;也可以通过你设置的classNamePrefix='select',查找类名含select-menu的容器。 - 模拟滚动到底部:给菜单容器设置
scrollTop = scrollHeight - clientHeight(即滚动到容器最底部),再触发滚动事件。 - 验证触发逻辑:通过监听
setSkip的调用,或检查skip值的变化,确认handleScroll是否被正确执行。
修改后的测试代码示例:
test("scroll in select triggers handleScroll", async () => { let value = jest.fn() let updateValue = jest.fn() let apiUrl = "/api/promoters/data" let ariaLabel = "selectPromoterFilter" const promotersOptions = [ { id: 0, label: "Select Promoter", value: "" }, { id: 1, label: "Ernesto Luna Hernández", value: 1 }, { id: 2, label: "María Fernanda Lopéz Barilla", value: 2 }, { id: 3, label: "Ricardo Gómez Robles", value: 3 }, { id: 4, label: "Ricardo Gómez Robles", value: 3 }, { id: 5, label: "Ricardo Gómez Robles", value: 5 }, { id: 6, label: "Ricardo Gómez Robles", value: 6 }, { id: 7, label: "Ricardo Gómez Robles", value: 7 }, { id: 8, label: "Ricardo Gómez Robles", value: 8 }, { id: 9, label: "Ricardo Gómez Robles", value: 9 }, { id: 10, label: "Final", value: 10 }, // 追加选项确保菜单出现滚动条 { id: 11, label: "Extra Option 1", value: 11 }, { id: 12, label: "Extra Option 2", value: 12 }, ] jest.spyOn(axios, 'get').mockResolvedValueOnce({ data: promotersOptions}); // 模拟setSkip用于验证 const mockSetSkip = jest.fn(); // 若组件内部用useState管理skip,可通过spy监听setSkip(示例:替换useState的返回) const originalUseState = React.useState; jest.spyOn(React, 'useState').mockImplementationOnce(initial => { const [state] = originalUseState(initial); return [state, mockSetSkip]; }); const { queryByLabelText, getByRole } = render( <Router> <Provider store={store}> <SelectApi value={value} updateValue={updateValue} apiUrl={apiUrl} ariaLabel={ariaLabel} /> </Provider> </Router> ) const selectPromoter = queryByLabelText(ariaLabel) if (selectPromoter) { // 点击打开下拉菜单 fireEvent.click(selectPromoter); // 等待菜单渲染完成,获取listbox容器 const menu = await waitFor(() => getByRole('listbox')); // 模拟滚动到底部的行为 fireEvent.scroll(menu, { target: { scrollTop: menu.scrollHeight - menu.clientHeight, scrollHeight: menu.scrollHeight, clientHeight: menu.clientHeight, }, }); // 验证handleScroll是否触发:检查setSkip是否被调用 expect(mockSetSkip).toHaveBeenCalled(); // 若用redux管理状态,可直接检查store中skip的数值变化 // expect(store.getState().yourNamespace.skip).toBe(limit); } })
关键细节:
- react-select的下拉菜单是独立DOM元素,不会挂载在你点击的select元素内部,必须单独定位。
- 只有当菜单滚动位置到达最底部时,
onMenuScrollToBottom才会触发,因此必须设置scrollTop = scrollHeight - clientHeight。 - 打开菜单后要用
waitFor确保菜单渲染完成,避免找不到元素的问题。
内容的提问来源于stack exchange,提问作者Laura
相关产品推荐
相关产品推荐

