React Jest测试失败:StlCron组件传参后输入值断言不匹配
Jest测试React StlCron组件自定义value不生效问题
问题描述
用Jest测试React的StlCron组件时,前两个无参测试(组件渲染、默认值验证)均通过,但第三个传入自定义value属性的测试失败,组件未正确接收传入的完整属性值。
测试报错信息
● Stl Cron component › cron input should have a passed Value in properties expect(element).toHaveValue(0 * * ? * * *0 0/15 8-17 ? * MON-FRI *) Expected the element to have value: 0 * * ? * * *0 0/15 8-17 ? * MON-FRI * Received: 0 * * ? * * *0 22 | render(<StlCron value={"0 * * ? * * *0 0/15 8-17 ? * MON-FRI *"} />); 23 | const stlCronInput = screen.getByTestId("stlCronInput"); > 24 | expect(stlCronInput).toHaveValue("0 * * ? * * *0 0/15 8-17 ? * MON-FRI *"); | ^ 25 | }); 26 | }); 27 |
React组件代码
import React, { useState } from "react"; import PropTypes from "prop-types"; import { Divider, Input } from "antd"; import { ReCron, Tab } from "@sbzen/re-cron"; import "./StlCron.scss"; const StlCron = ({ value, onChangeHandle, tabs }) => { const [cronValue, setCronValue] = useState(value ? value : "0 0 0 ? * * *"); return ( <div className="Stl-cron"> <Input data-testid="stlCronInput" value={cronValue} /> <Divider /> <ReCron renderYearsFrom={new Date().getFullYear()} renderYearsTo={new Date().getFullYear() + 10} value={cronValue} onChange={(value) => { onChangeHandle(value); setCronValue(value); }} tabs={tabs} /> </div> ); }; StlCron.propTypes = { tabs: PropTypes.arrayOf(PropTypes.string), onChangeHandle: PropTypes.func, }; StlCron.defaultProps = { tabs: [Tab.SECONDS, Tab.MINUTES, Tab.HOURS, Tab.DAY, Tab.MONTH, Tab.YEAR], onChangeHandle: () => {}, }; export default StlCron;
测试文件代码
import { cleanup, render, screen } from "@testing-library/react"; import StlCron from "./StlCron"; afterEach(() => { // cleanup(); }); describe("Stl Cron component", () => { it("should render stlCron component", () => { render(<StlCron />); const stlComponent = screen.getByTestId("stlCronInput"); expect(stlComponent).toBeInTheDocument(); }); it("cron input should have default Value when init", () => { render(<StlCron />); const stlCronInput = screen.getByTestId("stlCronInput"); expect(stlCronInput).toHaveValue("0 0 0 ? * * *"); }); it("cron input should have a passed Value in properties", () => { render(<StlCron value={"0 * * ? * * *0 0/15 8-17 ? * MON-FRI *"} />); const stlCronInput = screen.getByTestId("stlCronInput"); expect(stlCronInput).toHaveValue("0 * * ? * * *0 0/15 8-17 ? * MON-FRI *"); }); });
问题分析与解决方案
核心问题
- State未同步Props更新:组件用
useState初始化cronValue时,仅在首次渲染读取props.value,后续即便props.value变化,cronValue不会自动更新; - 传入值格式非法:你传入的
value是两段Cron表达式拼接的字符串,ReCron组件无法解析这种格式,会自动截断为它能识别的部分,导致最终显示的值不完整。
修复步骤
添加Props监听同步State:引入
useEffect监听props.value变化,实时更新cronValue:import React, { useState, useEffect } from "react"; // ... 其他导入代码 const StlCron = ({ value, onChangeHandle, tabs }) => { const [cronValue, setCronValue] = useState(value ? value : "0 0 0 ? * * *"); useEffect(() => { if (value) { setCronValue(value); } }, [value]); // ... 剩余组件代码 };传入合法Cron表达式:确保测试用的
value符合ReCron组件的格式要求,避免拼接非法字符串。如需测试多段Cron逻辑,应拆分单独测试。完善类型检查:给组件添加
value的PropTypes定义,提前发现类型错误:StlCron.propTypes = { tabs: PropTypes.arrayOf(PropTypes.string), onChangeHandle: PropTypes.func, value: PropTypes.string, };
内容的提问来源于stack exchange,提问作者cesar andavisa
相关产品推荐
相关产品推荐

