[英]Unexpected afterAll execution in Jest/Testing Library test suite
我正在 React 組件中測試一些異步行為,包括加載和錯誤狀態。 我通過使用設置狀態的不同describe
塊來接近不同的狀態,如下所示:
jest.spyOn(global, 'fetch');
describe('The App', () => {
const promiseWithDelay = (json, delay=0) =>
new Promise(resolve =>
setTimeout(
() => resolve({
ok: true,
json: () => json
}), delay
)
);
describe('given data loading', () => {
beforeEach(async () => {
global.fetch.mockImplementationOnce(() =>
promiseWithDelay(someData, 50)
);
await waitFor(() => render(<App />));
});
// ... successful tests for a loading state here
});
describe('some other tests', () => {
// ... more setup and other tests here
});
});
我正在通過模擬fetch
創建加載狀態
測試全部通過,但我收到Warning: Can't perform a React state update on an unmounted component.
錯誤,我認為這是因為在第二個describe
塊中的測試開始運行之前,第一個 describe 塊的render
沒有完全解決。
為了清除錯誤,我原本想在第一個describe
塊中包含一個afterAll
函數來等待創建加載狀態的Promise
解決,如下所示:
describe('The App', () => {
// ... etc
describe('given data loading', () => {
beforeEach(async () => {
// ... etc
});
// ... successful tests for a loading state here
afterAll(async () => {
await waitFor(() => {
expect(screen.queryByTestId('some-rendered-content')).toBeInTheDocument();
});
});
});
describe('some other tests', () => {
// ... more setup and other tests here
});
});
這並沒有清除錯誤,但是將afterAll
函數更改為afterAll
函數可以afterEach
。
完全困惑,我添加了一些控制台日志來查看什么時候發生了什么,並發現了這一點:
// afterEach console logs
beforeEach: Starting loading test
test: Testing loading
afterEach: Cleaning up from loading test
afterEach: Waiting for content to render
afterEach: Waiting for content to render
afterEach: Cleaned up from loading test
some other test: Starting next test
// afterAll console logs
beforeEach: Starting loading test
test: Testing loading
afterAll: Cleaning up from loading test
afterAll: Waiting for content to render
(console.error): Warning: Can't perform a React state update on an unmounted component. (etc.)
afterAll: Waiting for content to render
afterAll: Waiting for content to render
... afterAll: Waiting for content to render logs many times here
some other test: Starting next test
任何人都可以解釋這里的操作順序以及可能導致afterAll
但不是afterEach
警告的afterEach
嗎?
警告意味着被測試的組件有一些測試沒有等待的異步副作用(在這個測試套件中由fetch
表示)。
afterAll
應用於各自describe
一組測試,如果有多個測試,其中一些測試不會受到waitFor
中的afterAll
提供的延遲的影響。
正如與測試框架的集成所預期的那樣,React 測試庫會進行清理以使測試不會相互影響,而afterEach
是正確的地方。 正如文檔所述,
如果您使用的測試框架支持 afterEach 全局(如 mocha、Jest 和 Jasmine),則默認情況下每次測試后都會自動調用 Cleanup。
編寫測試的正確方法是在 RTL 清理之前等待組件內部的副作用完成。 這需要在每個測試中至少等待與副作用持續時間(50 毫秒)相同的時間,並且需要更多時間才能刷新承諾。 waitFor
的使用允許不依賴於實現細節。 由於副作用會影響測試結果,對於正確的位置waitFor
是beforeEach
或測試本身,而不是afterEach
或afterAll
。
同樣await waitFor(() => render(<App />))
沒有什么用處,因為它僅對拋出錯誤的函數有效,最常見的是斷言。 它可以簡化為render(<App />)
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.