在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();,但正则写法不正确,请问如何编写正确的正则匹配目标内容?
解决方案
你原来的写法存在两个错误:
queryByText接收正则参数时不能包裹在字符串里,需要直接传递正则字面量- 正则语法错误:
^是匹配行首的符号,放在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
相关产品推荐
相关产品推荐

