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

React动态表单组件测试:断言TextField类型与endAdornment属性

DataTableFormControl组件测试断言实现指南

问题背景

我开发了一个DataTableFormControl组件,会根据传入的dataType参数动态渲染不同表单控件:

const DataTableFormControl: FC<DataTableFormControlProp> = ({ displayName, isRequired, dataType, content, cellId }) => {

  return (
    (() => {
      switch (dataType) {
        case DataType.NUMBER:
          return <TextField
            id={cellId}
            label={displayName}
            defaultValue={content}
            required={isRequired}
            type="number"
          />
        case DataType.DATE:
          return <TextField
            id={cellId}
            label={displayName}
            defaultValue={content}
            type="date"
            required={isRequired}
          />
        case DataType.BOOLEAN:
          return <FormControl variant="standard">
            <Typography>{displayName}</Typography>
            <Switch color="primary" defaultChecked={content === 'true'} />
          </FormControl>
        case DataType.PERCENT:
          return <FormControl variant="standard">
            <Typography>{displayName}</Typography>
            <Input
              id={cellId}
              defaultValue={content}
              required={isRequired}
              endAdornment={<InputAdornment position="end">%</InputAdornment>}
            />
          </FormControl>
        default:
          return <TextField
            id={cellId}
            label={displayName}
            type="text"
            required={isRequired}
            defaultValue={content}
          />
      }
    })()
  )
};

export { DataTableFormControl };

目前已编写基础测试用例,但不清楚如何断言TextField的type属性,以及检查Input是否带有endAdornment:

describe('DataTableFormControl', () => {
  test('should render component with text dataType', () => {
    const { container } = renderControl(DataType.TEXT);
    const textElement = container.querySelector(`#${cellId}`);
    expect(textElement).toBeInTheDocument();
    // 如何断言元素的type是text/date/number?
    // 如何检查Input的endAdornment?
  });
});

解决方案

1. 断言TextField的type属性

TextField最终会渲染为原生input元素,可直接通过@testing-library/jest-dom提供的toHaveAttribute匹配器断言其type属性:

describe('DataTableFormControl', () => {
  // 测试文本类型
  test('should render text-type TextField for TEXT dataType', () => {
    const { container } = renderControl(DataType.TEXT);
    const inputElement = container.querySelector(`#${cellId}`);
    expect(inputElement).toBeInTheDocument();
    expect(inputElement).toHaveAttribute('type', 'text');
  });

  // 测试数字类型
  test('should render number-type TextField for NUMBER dataType', () => {
    const { container } = renderControl(DataType.NUMBER);
    const inputElement = container.querySelector(`#${cellId}`);
    expect(inputElement).toBeInTheDocument();
    expect(inputElement).toHaveAttribute('type', 'number');
  });

  // 测试日期类型
  test('should render date-type TextField for DATE dataType', () => {
    const { container } = renderControl(DataType.DATE);
    const inputElement = container.querySelector(`#${cellId}`);
    expect(inputElement).toBeInTheDocument();
    expect(inputElement).toHaveAttribute('type', 'date');
  });
});

2. 检查Input的endAdornment(PERCENT类型)

Input的endAdornment会渲染为带有特定类名的元素,可通过两种方式验证:

test('should render Input with percent endAdornment for PERCENT dataType', () => {
  const { container, getByText } = renderControl(DataType.PERCENT);
  const inputElement = container.querySelector(`#${cellId}`);
  expect(inputElement).toBeInTheDocument();
  
  // 方式1:直接查找%文本
  expect(getByText('%')).toBeInTheDocument();
  
  // 方式2:通过MUI的类名定位装饰元素
  const adornmentElement = container.querySelector('.MuiInputAdornment-end');
  expect(adornmentElement).toBeInTheDocument();
  expect(adornmentElement?.textContent).toBe('%');
});

3. 补充BOOLEAN类型的测试

针对布尔类型渲染的Switch,可断言其存在及选中状态:

test('should render Switch with correct checked state for BOOLEAN dataType', () => {
  // 测试选中状态
  const { getByRole } = renderControl(DataType.BOOLEAN, { content: 'true' });
  const switchElement = getByRole('switch');
  expect(switchElement).toBeInTheDocument();
  expect(switchElement).toBeChecked();

  // 测试未选中状态
  const { getByRole: getUncheckedSwitch } = renderControl(DataType.BOOLEAN, { content: 'false' });
  const uncheckedSwitch = getUncheckedSwitch('switch');
  expect(uncheckedSwitch).not.toBeChecked();
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 18:24:04