React Testing Library中自定义下拉框选择测试问题排查
React Testing Library测试自定义下拉框选择失效问题
我正在使用React Testing Library(RTL)测试自定义下拉框的选择功能,遇到了点击选项后值未更新的问题:点击选项后下拉框会关闭,但输入框中的选中值没有变化,预期的提示消息也未显示,导致测试断言失败。
调试细节
初始DOM结构
<div aria-expanded="false" aria-haspopup="true" aria-owns="contact-person_list" role="combobox" > <button aria-hidden="true" class="hidden-control nofocus" tabindex="-1" type="button" /> <span class="input-field input-field--active input-field--focus" > <span class="input-field__field" > <input aria-autocomplete="none" aria-controls="contact-person_list" aria-describedby="" aria-labelledby="contact-person_label" aria-readonly="true" autocomplete="off" class="input-field__input ellipsis" id="contact-person" readonly="" type="text" value="Passanger 1" /> </span> <label aria-label="Contact Person" class="input-field__placeholder" for="contact-person" id="contact-person_label" > Contact Customer </label> <span class="input-field__chevron" > <span aria-hidden="true" class="pictogram-wrapper" dir="auto" > <i class="icon icon-chevron-down" /> </span> </span> </span> <p aria-live="polite" class="auto-suggest__error-msg" role="region" /> </div>
打开下拉框的测试代码
const { getByRole, container, asFragment } = renderContactCardMock(passengerPersonEmptyMock); await userEvent.click(getByRole('textbox', { name: 'Contact Customer' })); expect(await screen.getByText('Travel Agent')).toBeInTheDocument(); // 确认下拉框已打开
下拉框打开后的DOM结构
<div class="popover pop-over hideDeskViewGroupListTitle enhanced-auto-suggest-v2-pop-over" data-auto="AutoSuggestFieldPopover" initialpositiondelay="0" style="width: 0px; top: 9px; left: 10px;" tabindex="-1" > <div class="popover__arrow" /> <div class="scroll scroll--visible" > <div class="scroll__box scroll__box--use-scroll" > <div> <div class="rich-text auto-suggest__group-list-title" > Contact Customer </div> <div class="auto-suggest modal-popover enhanced-auto-suggest-v2-popup" id="contact-person" role="listbox" tabindex="-1" > <div class="auto-suggest__list" > <button aria-selected="false" class="auto-suggest__item auto-suggest__highlight-selected-item" data-prevent-esc="true" role="option" type="button" > <div class="drop-down-item__dropdown" > <strong class="drop-down-item__dropdown-name" > Passenger 1 </strong> <span aria-hidden="true" class="pictogram-wrapper" dir="auto" > <i class="icon icon-check" /> </span> </div> </button> <button aria-selected="false" class="auto-suggest__item" data-prevent-esc="true" role="option" type="button" > <div class="drop-down-item__dropdown" > <strong class="drop-down-item__dropdown-name" > Travel Agent </strong> </div> </button> </div> </div> </div> </div> <div class="scroll__bar scroll__bar--visible" /> </div> </div>
选择选项的测试代码(断言失败)
await userEvent.click(screen.getByRole('option', {name : 'Travel Agent'})); expect(screen.getByText("Travel agent should add registered contact number")).toBeInTheDocument(); // 执行失败
可能的排查方向
- 检查
userEvent版本:确保使用@testing-library/user-event的最新版本,旧版本对自定义组件的事件模拟可能存在兼容性问题。 - 修正选项定位方式:选项的文本嵌套在
<strong>标签中,getByRole('option', {name: 'Travel Agent'})可能无法准确匹配,尝试通过文本定位后再找到对应的按钮:const travelAgentOption = screen.getByText('Travel Agent').closest('button[role="option"]'); await userEvent.click(travelAgentOption); - 等待状态异步更新:组件状态更新可能存在延迟,用
waitFor包裹断言,确保状态更新完成后再检查:await waitFor(() => { expect(screen.getByText("Travel agent should add registered contact number")).toBeInTheDocument(); }); - 验证组件事件绑定:确认自定义下拉框的
option按钮是否正确绑定了选择回调,点击时是否触发了onChange来更新父组件的选中值。 - 模拟键盘交互:尝试用键盘模拟真实用户选择流程,看是否能触发值更新:
await userEvent.click(getByRole('textbox', { name: 'Contact Customer' })); await userEvent.keyboard('{ArrowDown}{Enter}'); // 选中第二个选项并确认 await waitFor(() => { expect(screen.getByText("Travel agent should add registered contact number")).toBeInTheDocument(); });
内容的提问来源于stack exchange,提问作者Vivek Chauhan
相关产品推荐
相关产品推荐

