reactjs - @testing-library waitfor 在延迟加载的组件中找不到元素

标签 reactjs testing react-testing-library jsdom

我正在尝试使用@testing-library/react waitfor在比较快照之前等待延迟加载的组件。

App.tsx 就是这样:

const MyComponent = lazy(() => import('my/component'));

function App() {


  return (
    <Suspense
      fallback={
        <div>
          <h1>Loading&hellip;</h1>
        </div>
      }
    >
      <MyComponent />
    </Suspense>
  );

MyComponent是:

export const MyComponent = memo(() => {
  return <div data-testid='test' />;
});

测试是:

describe('<App />', () => {
  it('should render the App', async () => {
    const { container, findByTestId } = render(<App />);
    await waitFor(() => findByTestId('test'));
    expect(container.firstChild).toMatchSnapshot();
  });
});

waitFor超时因为findByTestId('test')没有找到该组件。如果我替换 <MyComponent /><div data-testid='test' />然后测试按预期工作。

如果延迟加载,为什么无法正确渲染?

亚当

最佳答案

来自React.lazy文档:

React.lazy takes a function that must call a dynamic import(). This must return a Promise which resolves to a module with a default export containing a React component.

这是 React.lazy 方法的签名:

function lazy<T extends ComponentType<any>>(
    factory: () => Promise<{ default: T }>
): LazyExoticComponent<T>;

所以工厂函数应该是:

const MyComponent = lazy(() => import('./component').then(({ MyComponent }) => ({ default: MyComponent })));

此外,您不需要将 waitForfindBy* 查询一起使用,因为:

findBy* methods are a combination of getBy* queries and waitFor

完整的工作示例:

component.tsx:

import React from 'react';
import { memo } from 'react';

export const MyComponent = memo(() => {
  return <div data-testid="test" />;
});

index.tsx:

import React, { lazy, Suspense } from 'react';

const MyComponent = lazy(() => import('./component').then(({ MyComponent }) => ({ default: MyComponent })));

export function App() {
  return (
    <Suspense
      fallback={
        <div>
          <h1>Loading&hellip;</h1>
        </div>
      }
    >
      <MyComponent />
    </Suspense>
  );
}

index.test.tsx:

import { render } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { App } from '.';

describe('<App />', () => {
  it('should render the App', async () => {
    const { container, findByTestId } = render(<App />);
    expect(container.firstChild).toMatchInlineSnapshot(`
      <div>
        <h1>
          Loading…
        </h1>
      </div>
    `);
    const mycomp = await findByTestId('test');
    expect(mycomp).toBeInTheDocument();
    expect(container.firstChild).toMatchInlineSnapshot(`
      <div
        data-testid="test"
      />
    `);
  });
});

测试结果:

 PASS  stackoverflow/71926928/index.test.tsx (11.382 s)
  <App />
    ✓ should render the App (78 ms)

---------------|---------|----------|---------|---------|-------------------
File           | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
---------------|---------|----------|---------|---------|-------------------
All files      |     100 |      100 |     100 |     100 |                   
 component.tsx |     100 |      100 |     100 |     100 |                   
 index.tsx     |     100 |      100 |     100 |     100 |                   
---------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   2 passed, 2 total
Time:        12.685 s

软件包版本:

"react": "^16.14.0",
"jest": "^26.6.3",
"@testing-library/react": "^11.2.7"

关于reactjs - @testing-library waitfor 在延迟加载的组件中找不到元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71926928/

相关文章:

javascript - React reducer(将对象键添加到对象)

reactjs - "gatsby-plugin-sharp"运行 gatsbydevelop 命令时找不到插件

testing - 测试平台解决方案

python - 在不同的测试类之间共享数据

reactjs - 如何查找不同元素的 getByRole 可用的属性?

reactjs - 如何使用 Jest 和 react-testing-library 测试 Websocket 客户端

reactjs - react 测试库 : Match Number of Buttons

javascript - React setState 来更新对象

python - 使用 python manage.py 测试应用程序的自定义 SimpleTestCase 子项的 ImportError

javascript - redux 中的应用程序与本地状态