使用jest和react-testing-library测试正确的SVG组件呈现

ut6juiuv  于 2022-12-08  发布在  Jest
关注(0)|答案(3)|浏览(244)

我在React组件中有一个svg,它可以有条件地呈现。

<div className='avatar'>
      {gender === true ? <MaleAvatar /> : <FemaleAvatar />}
    </div>

MaleAvatar和FemaleAvatar是包含svg的组件。最初,我希望MaleAvatar svg进行渲染,然后如果性别的值更改为false,则FemaleAvatar svg进行渲染-但男性化身应该首先渲染,这就是我想要测试的。
条件所在的组件是子组件的子组件,但我通过文本测试该组件中的元素,测试工作正常,例如:

const personDetailsText = screen.getByText('Personal details')

我正在使用jest和react-testing-library进行测试,但是在父div上使用测试id,然后获取第一个子div不起作用,因为它无法识别测试id。因此,如果我有:

<div data-testid='avatar' className='avatar'>
          {gender === true ? <MaleAvatar /> : <FemaleAvatar />}
        </div>

......则下面的测试在“const avatarSVG = screen.getByTestId('avatar')”处失败:

test('gender avatar is male on initialisation', () => {
    const avatarSVG = screen.getByTestId('avatar')
    expect(avatarSVG).toBeInTheDocument()
    expect(() => screen.getByTestId('female-avatar').toThrow())
    expect(avatar.firstChild.nodeName).toBe('MaleAvatar')
  })

我正在使用React钩子,我已经读到我也需要以某种方式补偿React渲染SVG后,初始渲染-后useEffect完成,但我找不到如何做这与React测试库和钩子?
这也行不通:

const avatarSVG = document.querySelector('MaleAvatar')

如何获取SVG组件以检查渲染的正确组件?

u0sqgete

u0sqgete1#

你可以用**screen.debug()**查看任何元素的内容,在你的svg元素中,根据这个内容你可以使用一个选择器:

import { render, screen } from "@testing-library/react";
screen.debug() // it shows the "dom"

在我的例子中,我使用FontAwesomeIcon,在使用debug之后,我可以看到:

<svg
            aria-hidden="true"
            class="svg-inline--fa fa-fire fa-w-12 "
            color="#FF9C31"
            data-icon="fire"
            data-prefix="fas"
            focusable="false"
            role="img"
            viewBox="0 0 384 512"
            xmlns="http://www.w3.org/2000/svg"
          >
          
          <path
              d="M216 23.86c0-23.8-30.65-32.77-44.15-13.04C48 191.85 224 200 224 288c0 35.63-29.11 64.46-64.85 63.99-35.17-.45-63.15-29.77-63.15-64.94v-85.51c0-21.7-26.47-32.23-41.43-16.5C27.8 213.16 0 261.33 0 320c0 105.87 86.13 192 192 192s192-86.13 192-192c0-170.29-168-193-168-296.14z"
              fill="currentColor"
            />
          </svg>

所以,我可以用

const { container } = render(<MyComponent />);

在我的例子[data-icon='fire']中使用一些选择器

const svgEl = container.querySelector("[data-icon='fire']") as HTMLImageElement;`

完成后,我还可以验证它是否具有特定的类

expect(svgEl.classList.toString()).toContain("fa-fire");
zc0qhyus

zc0qhyus2#

您是否尝试过为每个svg添加一个title属性?这样,您就可以使用getByTitle为svgAssert。

<div className='avatar'>
  {gender === true ? <MaleAvatar title="male" /> : <FemaleAvatar title="female" />}
</div>

在你的测试中

expect(getByTitle('male')).toBeInTheDocument();
expect(findByTitle('female')).not.toBeInTheDocument();

第二个测试使用findByTitle,因为如果它不在文档中,getBy*会使测试直接失败。
注意:要使这种方法生效,您需要将SVG文件导入为ReactComponent,如下所示:

import { ReactComponent as FemaleAvatar } from 'assets/images/FemaleAvatar.svg';
import { ReactComponent as MaleAvatar } from 'assets/images/MaleAvatar.svg';
u3r8eeie

u3r8eeie3#

你可以把await找svg:

await screen.getByTestId('id')

相关问题