React Testing Library报错排查与组件渲染验证及传参咨询
嘿,我来帮你搞定测试时遇到的这两个问题~
1. 先搞定组件渲染的必填参数问题
你碰到的No overload matches this call错误,核心原因很明确:你的Abc组件依赖的ShowProps类型里,post是必填属性,而且从组件代码来看,这个post对象得包含title、fullName、body这几个字段。
在Test.tsx里渲染组件时,你得先构造一个符合结构的测试用post对象,然后作为props传进去就行,比如:
// 先造个测试用的post数据 const mockPost = { title: "测试标题", fullName: "测试用户", body: "测试问题内容" }; // 渲染组件时把post传进去 render(<Abc post={mockPost} />);
另外提个小问题:你组件的render方法里直接用了post变量,但在Class组件里,props得通过this.props访问才行,不然会找不到post。所以组件代码得改成这样:
render() { const { post } = this.props; // 先从props里解构出post return ( <div className="Post-description"> <Title>{post.title}</Title> <hr/> <Name> {`${post.fullName}|${dateToString(currentDateTime)}`} </Name> <br/> <Question>{post.body}</Question> <hr/> <AllComments/> </div> ) }
不然就算传了props,组件还是会报错。
还有你用到的currentDateTime,如果是组件的state,记得在constructor里初始化;如果是props传进来的,测试时也要一起传入对应的参数哦。
2. 解决Cannot read property 'state' of undefined错误
这个错误一般是Class组件里的方法没有正确绑定this导致的。比如如果你的组件里有自定义的事件处理方法,用了普通函数写法,没绑定this的话,调用时this就会是undefined,自然读不到state。
举个例子,错误写法和修正方式:
// ❌ 错误写法:普通函数,this指向不对 handleCommentSubmit() { console.log(this.state.commentText); } // ✅ 修正方式1:用箭头函数定义方法,自动绑定this handleCommentSubmit = () => { console.log(this.state.commentText); } // ✅ 修正方式2:在constructor里手动绑定this constructor(props) { super(props); this.handleCommentSubmit = this.handleCommentSubmit.bind(this); }
如果这个错误是出在测试代码里,那你得检查下测试代码里是不是没正确获取组件实例就去访问state了,比如用了错误的方式获取组件,导致实例是undefined。
3. 验证所有组件是否渲染完成
当你正确传入props后,就可以用React Testing Library的查询方法来验证各个子组件是否正常渲染了,比如:
import { render, screen } from '@testing-library/react'; test('Abc组件渲染所有子组件', () => { const mockPost = { title: "测试标题", fullName: "测试用户", body: "测试问题内容" }; // 如果currentDateTime需要传参或者初始化,记得在这里处理好 render(<Abc post={mockPost} />); // 验证Title组件渲染了正确的标题文本 expect(screen.getByText("测试标题")).toBeInTheDocument(); // 验证Name组件里包含用户名 expect(screen.getByText(/测试用户/)).toBeInTheDocument(); // 验证Question组件渲染了问题内容 expect(screen.getByText("测试问题内容")).toBeInTheDocument(); // 验证AllComments组件存在(可以给它加个data-testid来查询) expect(screen.getByTestId("all-comments")).toBeInTheDocument(); });
内容的提问来源于stack exchange,提问作者EverydayDeveloper

