Jest.js React测试库无法找到包含文本的元素,即使该元素位于组件中

iecba09b  于 2022-12-08  发布在  Jest
关注(0)|答案(1)|浏览(293)

我正在学习测试我的应用程序与React测试库和笑话,我有一个问题,当我试图检查,如果一些文本是在一个组件内。
基本上,我有一个父组件(Pokemon.js)和一个子组件(Filters.js),我想通过测试Pokemon.js来验证Filters.js中是否存在一个单词
下面是我的测试:

import React from 'react'
import { render } from '@testing-library/react'
import Pokemon from '../../pages/index'
import '@testing-library/jest-dom'
import { TestQueryProvider } from '../helpers/test-utils'

test('Renders the Pokemon page', () => {
    render(<Pokemon />, { wrapper: TestQueryProvider });

    const { getByText } = render(<Pokemon />, { wrapper: TestQueryProvider });
    expect(getByText('Form')).toBeInTheDocument();
})

我尝试在getByText之前添加屏幕,并尝试写入/Form/i,但它返回相同的错误,即

TestingLibraryElementError: Unable to find an element with the text: Form. 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="sc-bjfHbI dxNTaY"
        >
          <span
            style="box-sizing: border-box; display: inline-block; overflow: hidden; background: none; opacity: 1; border: 
0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;"
          >
            <span
              style="box-sizing: border-box; display: block; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;"
            >
              <img
                alt=""
                aria-hidden="true"
                src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27192%27%20height=%27192%27/%3e"
                style="display: block; max-width: 100%; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;"
              />
            </span>
            <img
              alt=""
              data-nimg="intrinsic"
              decoding="async"
              src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
              style="position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; box-sizing: border-box; padding: 0px; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 
100%;"
            />
            <noscript />
          </span>
        </div>
      </div>
      <div>
        <div
          class="sc-bjfHbI dxNTaY"
        >
          <span
            style="box-sizing: border-box; display: inline-block; overflow: hidden; background: none; opacity: 1; border: 
0px; margin: 0px; padding: 0px; position: relative; max-width: 100%;"
          >
            <span
              style="box-sizing: border-box; display: block; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px; max-width: 100%;"
            >
              <img
                alt=""
                aria-hidden="true"
                src="data:image/svg+xml,%3csvg%20xmlns=%27http://www.w3.org/2000/svg%27%20version=%271.1%27%20width=%27192%27%20height=%27192%27/%3e"
                style="display: block; max-width: 100%; background: none; opacity: 1; border: 0px; margin: 0px; padding: 0px;"
              />
            </span>
            <img
              alt=""
              data-nimg="intrinsic"
              decoding="async"
              src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"
              style="position: absolute; top: 0px; left: 0px; bottom: 0px; right: 0px; box-sizing: border-box; padding: 0px; margin: auto; display: block; width: 0px; height: 0px; min-width: 100%; max-width: 100%; min-height: 100%; max-height: 
100%;"
            />
            <noscript />
          </span>
        </div>
      </div>
    </body>

       9 |
      10 |     const { getByText } = render(<Pokemon />, { wrapper: TestQueryProvider });
    > 11 |     expect(screen.getByText('Form')).toBeInTheDocument();
         |                   ^
      12 | })

问题是,我不知道这个HTML是从哪里来的,因为我检查了我的代码,没有任何东西具有这种结构。
什么是我的测试不起作用?
编辑:这是Filters.js中包含文本“Form”的部分

<PokedexDropdown>
    <label htmlFor='form'>Form</label>
    <select
        name='form'
        id='form'
        value={form}
        onChange={(e) => {
            setForm(e.target.value);
            setGeneration('all');
            setType('all');
        }}
    >
        <option value='default'>Default</option>
        <option value='regional - alola'>Regional - Alola</option>
        <option value='regional - galar'>Regional - Galar</option>
        <option value='regional - hisui'>Regional - Hisui</option>
        <option value='mega'>Mega</option>
        <option value='gmax'>Gmax</option>
    </select>
</PokedexDropdown>
mwg9r5ms

mwg9r5ms1#

问题是父组件Pokemon进行异步网络调用,当这些调用正在进行时,它返回加载显示而不是过滤器等。
当您在测试中挂载组件,然后尝试直接获取Form文本时,此Assert将在组件本身从加载状态切换出来之前执行。
为了解决这个问题,你通常会使用findByText而不是getByText,因为getByText会在后台为你轮询。你还需要使用await

import React from 'react'
import { render } from '@testing-library/react'
import Pokemon from '../../pages/index'
import '@testing-library/jest-dom'
import { TestQueryProvider } from '../helpers/test-utils'

test('Renders the Pokemon page', async () => {
    render(<Pokemon />, { wrapper: TestQueryProvider });

    const { findByText } = render(<Pokemon />, { wrapper: TestQueryProvider });
    let formText = await findByText('Form')
    expect(formText).toBeInTheDocument();
})

此外(您可能已经这样做了,如果是这样的话,请忽略),您将希望使用MSW或其他东西来模拟https://pokeapi.co API,因为您通常不希望在测试中依赖外部服务,因为它会破坏可重复性。

相关问题