@testing-library等待在惰性加载组件中找不到元素



我正在尝试使用@testing-library/reactwaitfor等待延迟加载的组件,然后再比较快照。

App.tsx简单如下:

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

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

MyComponentis:

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')没有找到组件。如果我用<div data-testid='test' />替换<MyComponent />,那么测试工作如预期。

为什么不能正确渲染如果它是惰性加载?

亚当

懒惰的医生:

React.lazy接受一个必须调用动态import()的函数。这必须返回一个Promise,它解析为一个包含React组件的default导出模块。

React.lazy方法的签名:

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

所以factory函数应该是:

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

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

findBy*方法是getBy*查询和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"

最新更新