我的組件:
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
我的測驗檔案:
describe("Test async", () => {
it("increments counter after 0.5s", async () => {
const { getByTestId, getByText } = render(<TestAsync />);
fireEvent.click(getByTestId("button-up"));
const counter = await waitForElement(() => getByTestId("counter"));
expect(counter).toHaveTextContent("1");
});
});
運行測驗檔案后,我收到錯誤訊息:
Expected element to have text content:
1
Received:
0
我有點困惑為什么我waitForElement用來獲取元素但為什么元素仍然具有舊值?
反應測驗庫版本 9.3.2
uj5u.com熱心網友回復:
首先,waitForElement已被棄用。使用find*查詢(首選:https ://testing-library.com/docs/dom-testing-library/api-queries#findby )或waitFor改用:https ://testing-library.com/docs/dom-testing-庫/api-async#waitfor
現在,我們使用waitFor:
waitFor可能會多次運行回呼,直到達到超時。
您需要將斷言陳述句包裝在waitFor. 這樣就waitFor可以多次運行回呼。如果將陳述句放在expect(counter).toHaveTextContent('1');陳述句之外和waitFor陳述句之后,則它只運行一次。斷言運行時,React 尚未更新。
為什么 RTL 會多次運行回呼(在超時前的每個間隔運行回呼)?
RTL 使用MutationObserver來監視對 DOM 樹所做的更改,請參見此處。請記住,我們的測驗環境是jsdom,它支持MutationObserver,看這里。
這意味著當 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
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/452775.html
