reactjs - 测试库:如何在函数返回时检查文本
问题描述
我有一个反应组件,它显示一个文本,其中一些单词可能会根据对象的值而改变
import React, { useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Card, Col, Row } from 'react-bootstrap';
function RenderPressMedia(props: any) {
const { t } = useTranslation();
const [pressPlanned, setPressPlanned] = useState<any[]>([]);
useEffect(() => {
if (!props.pressPlannedData) return;
setPressPlanned(props.pressPlannedData);
}, [props.pressPlannedData]);
const renderMedia = (media: string) => {
switch (media) {
case 'PHONE':
return t('press.media.phone');
case 'LETTER':
return t('press.media.letter');
case 'EMAIL':
return t('press.media.email');
case 'SMS':
return t('press.media.sms');
}
};
const renderPress = (media: string) => {
return (
<>
{t(`press.text`, {
media: renderMedia(media),
})}
</>
);
};
return (
<Row>
{pressPlanned.length > 0 &&
pressPlanned.map((press, index) => (
<Col lg={12} className="col-main" key={index}>
<Card>
<Card.Body>
<ul className="d-flex flex-row m-0 list-unstyled align-items-center">
<li aria-label="Reminder to do or reminder for today">
{renderPress(press.media)}
</li>
</ul>
</Card.Body>
</Card>
</Col>
))}
</Row>
);
}
export default RenderPressMedia;
renderPressMedia
函数返回一个翻译,该翻译将根据发送的变量而改变。运行良好的组件。
但是当我想用 对这个组件进行测试时testing-library
,我无法验证pressMedia
函数返回的内容。
这是进行的测试。
import React from 'react';
import { render, screen } from '@testing-library/react';
import RenderPressMedia from '../render-press-media';
const data: any[] = [
{
id: 65,
media: 'LETTER',
firstPlannedDate: '2021-09-03',
plannedDate: '2021-09-03',
comment: 'autogenerated',
createdDate: '2021-08-27T09:43:52',
lastModifiedDate: '2021-08-27T09:43:52',
},
];
describe('<RenderPressMedia/>', () => {
it('should display an render press media with data', () => {
//given
render(<RenderPressMedia pressPlannedData={data} />);
//then
expect(screen.getByText(/letter/i)).toBeInTheDocument();
});
});
测试包括验证函数返回的单词“字母”的存在pressMedia
expect(screen.getByText(/letter/i)).toBeInTheDocument();
但不幸的是,我收到一条错误消息
Unable to find an element with the text: /courrier/i. This could be because the
text is broken up by multiple elements. In this case, you can provide a function
for your text matcher to make your matcher more flexible.
Ignored nodes: comments, <script />, <style />
<body>
<div>
<div
class="row"
>
<div
class="col-main col-lg-12"
>
<div
class="card"
>
<div
class="card-body"
>
<ul
class="d-flex flex-row m-0 list-unstyled align-items-center"
>
<li
aria-label="Reminder to do or reminder for today"
>
press.text
</li>
</ul>
</div>
</div>
</div>
</div>
TestingLibraryElementError: Unable to find an element with the text: /courrier/i.
This could be because the text is broken up by multiple elements. In this case, you
can provide a function for your text matcher to make your matcher more flexible.
testingLibrairy 中的pressMedia
函数不返回其内容,因此无法验证单词letter的存在,返回值为press.text
如果您有解决此问题的解决方案。
解决方案
看起来,它的发生是因为您正在使用 i18n 函数,但它也被嘲笑,只是将作为参数接收的文本返回给您。
无论如何,在这种情况下,您所做的一切都很好。但你也在测试翻译。因此,它可能更复杂且难以维护。
因此,我建议测试它是否使用正确的媒体,例如:
<li aria-label="Reminder to do or reminder for today" data-testid="component" data-media={press.media}>
{renderPress(press.media)}
</li>
在测试部分:
expect(screen.getByTestId('component')).toHaveAttribute('data-media', data.media);
在这种情况下,忽略语言,您知道哪种媒体具有您的组件。
我创建了这个 github repo 作为示例:
- 回购:https ://github.com/joseglego/test-testing-library/
- 组件:https ://github.com/joseglego/test-testing-library/blob/main/src/RenderPressMedia.js
- 测试:https ://github.com/joseglego/test-testing-library/blob/main/src/RenderPressMedia.test.js
- 具体提交:https ://github.com/joseglego/test-testing-library/commit/f3c222f92313c909c8d4a1f359daf01bdd0f880d
基本上,该测试在我的本地运行。
推荐阅读
- visual-studio - Microsoft.Office.Core.CustomTaskPane 和 Microsoft.Office.Tools.CustomTaskPane.. 有什么区别?
- git - 使用 psexec 时无法运行 git clone
- javascript - 在孩子之后删除所有下一个 div
- html - Express.js 不发送 css 文件
- python-3.x - 使用列表理解初始化 Python 字典
- android - 在 Android Studio 中使用 SignalR 时出错
- python - 破坏不同类别的 tkinter 屏幕
- ios - UITableView 的关闭捕获内存泄漏问题
- python - Flask:request,返回上一个请求的状态信息
- c#-8.0 - MaybeNull 属性警告空引用返回