Vite React项目中Jest hasFocus()断言匹配失败问题求助
从Create React App迁移到Vite后,React Testing Library的
hasFocus()断言失败问题 问题说明
从Create React App迁移到Vite后,使用React Testing Library(RTL)测试点击关联label时email、password输入框是否获得焦点,hasFocus()匹配器断言失败。HTML标签关联逻辑正常,但测试中hasFocus()匹配的是整个文档(body)而非目标输入框。
相关代码
Login组件
function Login() { return ( <div> <p>Some text</p> <div> <label htmlFor="email">Email</label> <input type="email" name="email" id="email" /> <label htmlFor="password">Password</label> <input type="text" name="password" id="password" /> <button>OK</button> </div> </div> ) }
单元测试代码
test('it should check that the email input element will be focused whenever the associated label is clicked', () => { render(<Login />) const emailLabel = screen.getByLabelText('Email'); const emailInput = screen.getByRole('textbox', {name: email}); logRoles(emailInput, emailLabel) fireEvent.click(emailLabel); expect(emailInput).toHaveFocus(); })
依赖包配置
{ "name": "my-app", "private": true, "version": "0.0.0", "type": "module", "scripts": { "dev": "vite", "build": "vite build", "lint": "eslint . --ext js,jsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview", "test": "jest" }, "dependencies": { "@babel/preset-env": "^7.22.10", "@babel/preset-react": "^7.22.5", "identity-obj-proxy": "^3.0.0", "react": "^18.2.0", "react-dom": "^18.2.0", "styled-components": "^6.0.7" }, "devDependencies": { "@testing-library/jest-dom": "^6.0.0", "@testing-library/react": "^14.0.0", "@testing-library/user-event": "^14.4.3", "@types/react": "^18.2.15", "@types/react-dom": "^18.2.7", "@vitejs/plugin-react": "^4.0.3", "eslint": "^8.45.0", "eslint-plugin-react": "^7.32.2", "eslint-plugin-react-hooks": "^4.6.0", "eslint-plugin-react-refresh": "^0.4.3", "jest": "^29.6.2", "jest-environment-jsdom": "^29.6.2", "vite": "^4.4.5" }, "jest": { "testEnvironment": "jsdom", "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/fileTransformer.js", "^.+\\.(css|less|scss)$": "identity-obj-proxy" }, "setupFilesAfterEnv": [ "<rootDir>/setupTests.js" ] } }
错误信息
expect(element).toHaveFocus() Expected element with focus: <input id="password" name="Password" type="text" /> Received element with focus: <body><div><div class="App-body"><p>Login to access the full dashboard</p><div class="form"><label for="email">Email</label><input id="email" name="Email" type="email" /><label for="password">Password</label><input id="password" name="Password" type="text" /><button>OK</button></div></div></div></body> 38 | fireEvent.click(passwordLabel); 39 | > 40 | expect(passwordInput).toHaveFocus(); | ^ 41 | }); 42 | at Object.toHaveFocus (src/Login/Login.spec.js:40:25)
解决建议
- 修正输入框选择器参数:测试代码中
screen.getByRole('textbox', {name: email})的name参数未定义,应改为字符串'Email'或'email'(匹配输入框name属性或label文本)。 - 使用
userEvent替代fireEvent:RTL新版本推荐用userEvent模拟真实用户交互,fireEvent作为低级API可能无法触发label点击后的焦点行为,替换为userEvent.click(emailLabel)。 - 检查依赖兼容性:确认
jest-environment-jsdom、@testing-library/jest-dom与Jest、RTL的版本是否匹配,避免版本冲突导致的异常。 - 验证测试初始化配置:确保
setupTests.js中已正确导入@testing-library/jest-dom(如import '@testing-library/jest-dom';),否则toHaveFocus匹配器无法正常工作。
内容的提问来源于stack exchange,提问作者Moez Ben Rebah
相关产品推荐
相关产品推荐

