You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 *");
  });
});

问题分析与解决方案

核心问题

  1. State未同步Props更新:组件用useState初始化cronValue时,仅在首次渲染读取props.value,后续即便props.value变化,cronValue不会自动更新;
  2. 传入值格式非法:你传入的value是两段Cron表达式拼接的字符串,ReCron组件无法解析这种格式,会自动截断为它能识别的部分,导致最终显示的值不完整。

修复步骤

  1. 添加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]);
    
      // ... 剩余组件代码
    };
    
  2. 传入合法Cron表达式:确保测试用的value符合ReCron组件的格式要求,避免拼接非法字符串。如需测试多段Cron逻辑,应拆分单独测试。

  3. 完善类型检查:给组件添加value的PropTypes定义,提前发现类型错误:

    StlCron.propTypes = {
      tabs: PropTypes.arrayOf(PropTypes.string),
      onChangeHandle: PropTypes.func,
      value: PropTypes.string,
    };
    

内容的提问来源于stack exchange,提问作者cesar andavisa

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 11:39:47