gpt4 book ai didi

reactjs - 如何使用React测试库通过包含html标签的文本字符串进行查询?

转载 作者:行者123 更新时间:2023-12-03 13:15:51 25 4
gpt4 key购买 nike

当前工作解决方案

使用此 html:

<p data-testid="foo">Name: <strong>Bob</strong> <em>(special guest)</em></p>

我可以使用React Testing Library用于查找 textContentgetByTestId 方法:

expect(getByTestId('foo').textContent).toEqual('Name: Bob (special guest)')

有更好的方法吗?

我想简单地使用这个html:

<p>Name: <strong>Bob</strong> <em>(special guest)</em></p>

并使用React Testing LibrarygetByText 方法如下:

expect(getByText('Name: Bob (special guest)')).toBeTruthy()

但这不起作用。

所以,问题......

是否有更简单的方法来使用 React 测试库来查找带标签的文本内容字符串?

最佳答案

更新2

经过多次使用,我创建了一个助手。下面是使用此助手的示例测试。

测试助手:

// withMarkup.ts
import { MatcherFunction } from '@testing-library/react'

type Query = (f: MatcherFunction) => HTMLElement

const withMarkup = (query: Query) => (text: string): HTMLElement =>
query((content: string, node: HTMLElement) => {
const hasText = (node: HTMLElement) => node.textContent === text
const childrenDontHaveText = Array.from(node.children).every(
child => !hasText(child as HTMLElement)
)
return hasText(node) && childrenDontHaveText
})

export default withMarkup

测试:

// app.test.tsx
import { render } from '@testing-library/react'
import App from './App'
import withMarkup from '../test/helpers/withMarkup'

it('tests foo and bar', () => {
const { getByText } = render(<App />)
const getByTextWithMarkup = withMarkup(getByText)
getByTextWithMarkup('Name: Bob (special guest)')
})
<小时/>

更新 1

下面是创建新匹配器 getByTextWithMarkup 的示例。请注意,此函数在测试中扩展了 getByText,因此必须在那里定义它。 (当然,该函数可以更新为接受 getByText 作为参数。)

import { render } from "@testing-library/react";
import "jest-dom/extend-expect";

test("pass functions to matchers", () => {
const Hello = () => (
<div>
Hello <span>world</span>
</div>
);
const { getByText } = render(<Hello />);

const getByTextWithMarkup = (text: string) => {
getByText((content, node) => {
const hasText = (node: HTMLElement) => node.textContent === text
const childrenDontHaveText = Array.from(node.children).every(
child => !hasText(child as HTMLElement)
)
return hasText(node) && childrenDontHaveText
})
}

getByTextWithMarkup('Hello world')
})
<小时/>

这是 Five Things You (Probably) Didn't Know About Testing Library 4 日的可靠答案来自Giorgio Polvara's Blog :

<小时/>

查询也接受函数

您可能见过这样的错误:

Unable to find an element with the text: Hello world.This could be because the text is broken up by multiple elements.In this case, you can provide a function for your textmatcher to make your matcher more flexible.

通常,发生这种情况是因为您的 HTML 如下所示:

<div>Hello <span>world</span></div>

解决方案包含在错误消息中:“[...]您可以为您的文本匹配器提供一个函数[...]”。

这是怎么回事?事实证明,匹配器接受字符串、正则表达式或函数。

为您正在渲染的每个节点调用该函数。它接收两个参数:节点的内容和节点本身。您所要做的就是根据该节点是否是您想要的节点返回 true 或 false。

一个例子可以阐明它:

import { render } from "@testing-library/react";
import "jest-dom/extend-expect";

test("pass functions to matchers", () => {
const Hello = () => (
<div>
Hello <span>world</span>
</div>
);
const { getByText } = render(<Hello />);

// These won't match
// getByText("Hello world");
// getByText(/Hello world/);

getByText((content, node) => {
const hasText = node => node.textContent === "Hello world";
const nodeHasText = hasText(node);
const childrenDontHaveText = Array.from(node.children).every(
child => !hasText(child)
);

return nodeHasText && childrenDontHaveText;
});
});

我们忽略 content 参数,因为在本例中,它将是“Hello”、“world”或空字符串。

我们检查的是当前节点是否具有正确的textContenthasText 是一个用于执行此操作的小辅助函数。我声明它是为了保持干净。

但这还不是全部。我们的 div 并不是包含我们要查找的文本的唯一节点。例如,本例中的 body 具有相同的文本。为了避免返回超出需要的节点,我们确保没有一个子节点与其父节点具有相同的文本。通过这种方式,我们可以确保返回的节点是最小的,换句话说,该节点靠近 DOM 树的底部。

<小时/>

阅读 Five Things You (Probably) Didn't Know About Testing Library 的其余部分

关于reactjs - 如何使用React测试库通过包含html标签的文本字符串进行查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55509875/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com