测试库:如何在函数返回文本时检查文本

Testing-librairy : How to check a text when it is returned by a function

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

 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 函数 returns 翻译将根据发送的变量而改变。 效果很好的组件。

但是当我想用testing-library对该组件进行测试时,我无法验证return由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函数

编辑的单词“字母”return是否存在
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 函数没有 return 其内容,因此无法验证单词 letter、return 值的存在是 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 回购作为示例:

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