首先,waitForElement
已被弃用。用一个find*
查询(首选:https://testing-library.com/docs/dom-testing-library/api-queries#findby https://testing-library.com/docs/dom-testing-library/api-queries#findby)或使用waitFor
反而:https://testing-library.com/docs/dom-testing-library/api-async#waitfor https://testing-library.com/docs/dom-testing-library/api-async#waitfor
现在,我们使用waitFor
:
waitFor
可能会多次运行回调,直到达到超时。
您需要将断言语句包装在回调的内部waitFor
。以便waitFor
可以多次运行回调。如果你把expect(counter).toHaveTextContent('1');
外部和之后的声明waitFor
语句,那么它只运行一次。断言运行时 React 尚未更新。
为什么RTL会多次运行回调(超时前每隔一段时间运行回调)?
RTL use 变异观察者 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver要监视对 DOM 树所做的更改,请参阅here https://github.com/testing-library/dom-testing-library/blob/main/src/wait-for.js#L110。请记住,我们的测试环境是jsdom
,它支持MutationObserver
, see here https://github.com/jsdom/jsdom/issues/639#issuecomment-816851899.
这意味着当 React 更新状态并将更新应用到 DOM 时,可以检测到 DOM 树的更改,并且 RTL 将再次运行回调(包括断言)。当 React 组件状态被应用并变得稳定时,回调的最后一次运行将被视为测试的最终断言。如果断言失败,则报告错误,否则测试通过。
所以工作示例应该是:
index.tsx
:
import React from 'react';
const TestAsync = () => {
const [counter, setCounter] = React.useState(0);
const delayCount = () =>
setTimeout(() => {
setCounter(counter + 1);
}, 500);
return (
<>
<h1 data-testid="counter">{counter}</h1>
<button data-testid="button-up" onClick={delayCount}>
Up
</button>
<button data-testid="button-down" onClick={() => setCounter(counter - 1)}>
Down
</button>
</>
);
};
export default TestAsync;
index.test.tsx
:
import { fireEvent, render, waitFor } from '@testing-library/react';
import React from 'react';
import TestAsync from '.';
import '@testing-library/jest-dom/extend-expect';
describe('Test async', () => {
it('increments counter after 0.5s', async () => {
const { getByTestId } = render(<TestAsync />);
fireEvent.click(getByTestId('button-up'));
await waitFor(() => {
const counter = getByTestId('counter');
expect(counter).toHaveTextContent('1');
});
});
});
测试结果:
PASS stackoverflow/71639088/index.test.tsx
Test async
✓ increments counter after 0.5s (540 ms)
-----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
-----------|---------|----------|---------|---------|-------------------
All files | 88.89 | 100 | 75 | 88.89 |
index.tsx | 88.89 | 100 | 75 | 88.89 | 17
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.307 s