React表单单元测试报错找不到data-testid=input-first-name元素
问题根因
你的判断是对的,报错核心原因就是外层isLoggedIn === "true"的条件渲染判断未通过,包含输入框的整个表单块根本没有挂载到DOM中,自然找不到data-testid="input-first-name"的元素。
当前测试代码渲染组件时仅传入了show={true}属性,没有处理isLoggedIn状态的初始值,默认状态下该值不等于字符串"true",三元表达式直接走了返回空内容的分支,表单完全没有渲染。
修复方案
登录态场景适配:测试渲染组件前先把
isLoggedIn的状态调整为满足判断条件的值
从你用=== "true"判断的写法来看,这个值大概率存在localStorage中,在render前提前写入对应值即可:it('should render the component onto the screen', () => { // 提前写入登录态,触发表单区域渲染 window.localStorage.setItem('isLoggedIn', 'true') render(<BrowserRouter><AddUsers show={true}/> </BrowserRouter>); // 修正原有错误断言:getByTestId返回DOM节点,判断输入框值需要用toHaveValue匹配器 expect(screen.getByTestId('input-first-name')).toHaveValue(""); });如果
isLoggedIn是从Redux、Context或者组件props获取的,对应在测试中传入正确的mock状态、Provider包裹或者传参即可,保证isLoggedIn === "true"的判断成立。未登录态场景适配:如果要测试未登录的渲染逻辑,不要查找登录后才显示的表单元素,反过来断言元素不存在即可:
it('should hide add user form when user is not logged in', () => { render(<BrowserRouter><AddUsers show={true}/> </BrowserRouter>); // 判断元素不存在必须用queryBy*方法,getBy*找不到元素会直接抛出和你现在一样的报错 expect(screen.queryByTestId('input-first-name')).not.toBeInTheDocument(); });
其他需要修正的细节
- 原断言写法错误:
screen.getByTestId('input-first-name')返回的是真实DOM节点对象,不可能和空字符串""相等,判断输入框的值要使用@testing-library/jest-dom提供的toHaveValue()匹配器,或者判断元素的.value属性。 - 测试文件中不需要引入未使用的方法,比如当前引入的
getByTestId、waitFor、fireEvent、act、userEvent如果对应用例没用到,可以暂时删除减少冗余。
内容的提问来源于stack exchange,提问作者Anks
相关产品推荐
相关产品推荐

