@testing-library中userEvent.selectOptions无法选中下拉选项的问题解决
解决React下拉菜单组件的@testing-library测试问题
组件代码
const DropdownMenu = () => { return ( <div className="dropdown-menu__container"> <select id="selectCity"> <option>Mars</option> <option>Saturn</option> <option>Venus</option> </select> </div> ); };
测试代码
it("should call handleTestNameChange with the new value when the selection changes", () => { render(<DropdownMenu />); const selectElement = screen.getByRole("combobox"); console.log("before select options ", selectElement.value); userEvent.selectOptions(selectElement, "Saturn"); expect(selectElement).toHaveValue("Saturn"); });
问题与控制台输出
测试执行后未按预期通过,控制台输出如下:
Console console.log before select options Mars at Object.<anonymous> (src/components/batchrec/dropdown-menu/dropdown-menu.test.js:39:13) ● DropdownMenu component › should call handleTestNameChange with the new value when the selection changes expect(element).toHaveValue(Saturn) Expected the element to have value: Saturn Received: Mars 39 | console.log("before select options ", selectElement.value); 40 | userEvent.selectOptions(selectElement, "Saturn"); > 41 | expect(selectElement).toHaveValue("Saturn"); | ^ 42 | }); 43 | }); 44 |
核心问题:测试中userEvent.selectOptions未能成功选中目标选项,断言失败。
环境配置
"dependencies": { "@testing-library/jest-dom": "^5.16.5", "@testing-library/react": "^13.4.0", "date-fns": "^2.29.3", "react": "^18.2.0", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-router-dom": "^6.9.0", "react-scripts": "5.0.1", "recharts": "^2.5.0", "sass": "^1.62.0", "tachyons": "^4.12.0", "web-vitals": "^2.1.4" }, "devDependencies": { "@babel/core": "^7.21.4", "@babel/plugin-transform-modules-commonjs": "^7.21.2", "@babel/preset-env": "^7.21.4", "@testing-library/user-event": "^14.4.3", "babel-jest": "^29.5.0" }
解决方案
问题根源
你的<option>未显式设置value属性,虽然浏览器会默认将文本内容作为value,但@testing-library/user-event的selectOptions方法在这种场景下无法稳定匹配文本内容来选中选项,导致操作失效。
修复方案一(推荐:规范组件代码)
给每个<option>添加与文本一致的value属性,让select的取值逻辑更明确:
const DropdownMenu = () => { return ( <div className="dropdown-menu__container"> <select id="selectCity"> <option value="Mars">Mars</option> <option value="Saturn">Saturn</option> <option value="Venus">Venus</option> </select> </div> ); };
修改后原测试代码无需改动,即可正常通过。
修复方案二(无需修改组件,调整测试逻辑)
如果不想改动组件代码,可以直接通过获取目标option元素的方式来完成选中操作:
it("should update the selected value when the selection changes", () => { render(<DropdownMenu />); const selectElement = screen.getByRole("combobox"); // 获取目标option元素 const saturnOption = screen.getByText("Saturn"); userEvent.selectOptions(selectElement, saturnOption); expect(selectElement).toHaveValue("Saturn"); });
关键说明
- 显式设置
value是HTML表单元素的规范写法,能避免浏览器默认行为带来的测试不确定性。 - @testing-library/user-event v14+版本的
selectOptions支持传入元素对象或value字符串,只需保证传入的参数与元素属性匹配即可。
内容的提问来源于stack exchange,提问作者peterphonic
相关产品推荐
相关产品推荐

