首页 > 解决方案 > 测试库:如何在函数返回时检查文本

问题描述

我有一个反应组件,它显示一个文本,其中一些单词可能会根据对象的值而改变

 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

如果您有解决此问题的解决方案。

标签: reactjsreact-testing-library

解决方案


看起来,它的发生是因为您正在使用 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 作为示例:

基本上,该测试在我的本地运行。


推荐阅读