React含reduce方法组件的React Testing+Jest测试报错解决方案
问题
使用React Testing Library的render方法测试AuthorsGroup组件时出现报错,错误截图如下:
测试代码
import { render, screen } from "@testing-library/react"; import AuthorsGroup from "./Authorsgroup"; it("should render author component", () => { render(<AuthorsGroup />); const headerEl = screen.getByRole("heading", { name: /happyusertapesh/i }); expect(headerEl).toBeInTheDocument(); });
AuthorsGroup组件代码
const Authorsgroup = ({ posts, groupDropdownValue, setShowForm, setPostId, showForm }) => { const authorGroup = posts.reduce((group, authorgroup) => { (group[authorgroup.author.replace(/ +/g, "")] = group[authorgroup.author.replace(/ +/g, "")] || []).push(authorgroup); return group; }, {}); const [authorGroupValues, setAuthorGroupValues] = useState(authorGroup); const authorGroupEntries = Object.entries(authorGroupValues); useEffect(() => { setAuthorGroupValues(authorGroup); }, [groupDropdownValue, showForm]); return ( <> <Container> <Container style={{ marginTop: "3rem" }}> {authorGroupEntries.map(([author, posts]) => { return ( <div key={author}> <Accordion> <AccordionSummary expandIcon={<ExpandMoreIcon />} aria-controls="panel1a-content" id="panel1a-header" > <Typography variant="h6" style={{ color: "#EB1283" }}> {author} </Typography> </AccordionSummary> {posts.map(({ id, text, author, location }) => { return ( <div key={id}> <AccordionDetails> <Typography variant="h4"> {id} {author} </Typography> <Typography> {text} {location} </Typography> <Button variant="outlined" onClick={() => { setShowForm(!showForm); setPostId(id); }} startIcon={<EditIcon />} > Edit </Button> </AccordionDetails> </div> ); })} </Accordion> </div> ); })} </Container> </Container> </> ); }; export default Authorsgroup;
解决方案
错误原因
报错源于测试时未给组件传入posts props,导致组件执行posts.reduce()时因posts为undefined抛出错误。此外组件依赖的setShowForm、setPostId等props也未传入,会引发后续错误。
解决步骤
传入模拟props数据
在测试中给组件传入模拟的posts数据,以及必要的回调函数和状态值:import { render, screen } from "@testing-library/react"; import AuthorsGroup from "./Authorsgroup"; it("should render author component", () => { // 模拟测试用的posts数据 const mockPosts = [ { id: 1, text: "Sample post content", author: "happyusertapesh", location: "Sample location" } ]; // 用jest.fn()创建模拟回调函数 const mockSetShowForm = jest.fn(); const mockSetPostId = jest.fn(); render( <AuthorsGroup posts={mockPosts} groupDropdownValue="" setShowForm={mockSetShowForm} setPostId={mockSetPostId} showForm={false} /> ); const headerEl = screen.getByRole("heading", { name: /happyusertapesh/i }); expect(headerEl).toBeInTheDocument(); });给组件设置默认props(可选优化)
在组件中添加默认props,避免因未传入props导致报错,同时简化测试代码:Authorsgroup.defaultProps = { posts: [], groupDropdownValue: "", setShowForm: () => {}, setPostId: () => {}, showForm: false };设置后,测试时可只传入必要的
posts数据,其他props会自动使用默认值。
内容的提问来源于stack exchange,提问作者Tapesh Patel
相关产品推荐
相关产品推荐

