You need to enable JavaScript to run this app. 在testing library中如何使用正则表达式匹配预期渲染字符串
优惠活动
大模型
产品
解决方案
定价
更多

在testing library中如何使用正则表达式匹配预期渲染字符串

问题场景

我正在测试一个React组件,点击「Adicionar ao final」(添加到末尾)或「Adicionar ao início」(添加到开头)按钮后,页面会渲染如下格式的内容:

Id:1627223765317 Valor:1627223765317
Id:1627223765150 Valor:1627223765150

我需要编写测试验证这些内容是否正常渲染。

组件代码

/* eslint-disable no-underscore-dangle */
/* eslint-disable react/no-this-in-sfc */
/* eslint-disable jsx-a11y/control-has-associated-label */
/* eslint-disable react/button-has-type */
import React, { useState } from 'react';
import PageDefault from '../../components/PageDefault';
import './index.scss';

function Keys() {
  const [objects, setObjects] = useState([]);
  return (
    <PageDefault>
      <form onSubmit={(event) => event.preventDefault()}>
        <div className="buttons-inputs">
          <button onClick={() => setObjects([
            {
              id: +new Date().valueOf(),
              valor: +new Date().valueOf(),
            },
            ...objects,
          ])}
          >
            Adicionar ao início
          </button>
          <button onClick={() => setObjects([
            ...objects,
            {
              id: +new Date().valueOf(),
              valor: +new Date().valueOf(),
            },
          ])}
          >
            Adicionar ao final
          </button>
          <button onClick={
          () => setObjects(objects.filter((object) => object.id !== objects[0].id))
        }
          >
            Remover do início
          </button>
          <button onClick={() => {
            setObjects(objects.filter((object) => object.id !== objects[objects.length - 1].id));
          }}
          >
            Remover do final
          </button>
        </div>
        <div className="lists">
          <div className="list-id">
            <h2>ID:</h2>
            {objects.map((object) => (
              <h1 key={object.id}>
                Id:
                {object.id}
                {' '}
                Valor:
                {object.valor}
              </h1>
            ))}
          </div>
          <div className="list-index">
            <h2>Index</h2>
            {objects.map((object, index) => (
              // eslint-disable-next-line react/no-array-index-key
              <h1 key={index}>
                Id:
                {object.id}
                {' '}
                Valor:
                {object.valor}
              </h1>
            ))}
          </div>
        </div>
      </form>
    </PageDefault>
  );
}

export default Keys;

现有测试代码

import { fireEvent, render } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Keys from './index';

describe('Testing the rendering of components', () => {
  test('component mounts successfully', () => {
    render(
      <MemoryRouter>
        <Keys />
      </MemoryRouter>,
    );
  });
  test('content renders correctly after adding item to start', () => {
    const { getByText, queryByText } = render(
      <MemoryRouter>
        <Keys />
      </MemoryRouter>,
    );

    fireEvent.click(getByText('Adicionar ao início'));
    expect(queryByText('Valor:^/0-9/i')).toBeInTheDocument();
  });
});

我目前写的断言是expect(queryByText('Valor:^/0-9/i')).toBeInTheDocument();,但正则写法不正确,请问如何编写正确的正则匹配目标内容?

解决方案

你原来的写法存在两个错误:

  1. queryByText 接收正则参数时不能包裹在字符串里,需要直接传递正则字面量
  2. 正则语法错误:^ 是匹配行首的符号,放在Valor:后面无法匹配,数字匹配的写法也不对

正确的正则写法如下:

/Valor:\s*\d+/i

各部分含义:

  • /.../i 是JS正则字面量的标准写法,末尾的i代表忽略大小写匹配,如果你不需要可以去掉
  • Valor: 匹配固定前缀文本
  • \s* 匹配Valor:后面可能存在的任意数量空格(你组件代码里Valor:和数值之间有个空格,加这个更兼容)
  • \d+ 匹配1个及以上的数字,正好对应你生成的时间戳数值

如果需要更严谨匹配整行格式,可以用下面的正则:

/Id:\s*\d+\s+Valor:\s*\d+/i

修改后的断言代码:

expect(queryByText(/Valor:\s*\d+/i)).toBeInTheDocument();

另外补充一个优化点:你原来的两个测试用例名字重复了,建议修改成不同的语义化名称,避免测试报告混乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 11:09:00