1.我读到act / waitFor是等待DOM更新。我也读到渲染是同步的。我假设我不需要用act/waitFor Package Render,因为DOM总是在我单击或测试时更新?是这样吗?
1.接下来,我不明白为什么我需要act / waitFor?**我不能只做一个等待吗?**对于测试A,我使用user.click,我看到在线示例代码使用await。在我的笔记本电脑上似乎工作得很好。
然而在测试B中,当我看到www.example.com的一些示例代码fireEvent.click,他们使用waitFor。我尝试使用await,它标记我“await对这种类型的表达式没有影响”。但是“await waitFor()”可以工作。这是为什么呢?
非常感谢提前!
Test A
it('user.click', async () => {
render(
<BrowserRouter>
<Notes />
</BrowserRouter>
);
const checkBox = screen.getByRole('checkbox');
await user.click(checkBox);
const prev = screen.getByRole('button', { name: 'Prev' });
expect(prev).toBeEnabled();
});
Test B
it('fireEvent.click', async () => {
render(
<BrowserRouter>
<Notes />
</BrowserRouter>
);
const checkBox = screen.getByRole('checkbox');
await fireEvent.click(checkBox);
const prev = screen.getByRole('button', { name: 'Prev' });
expect(prev).toBeEnabled();
});
1条答案
按热度按时间gwbalxhn1#
我尝试使用await,它标记我“await对这种类型的表达式没有影响”。但是“await waitFor()”可以工作。这是为什么呢?
await
是将回调附加到promise的语法糖;一旦promise被解析或拒绝,异步函数的其余部分将继续执行。例如,写
await 3
是没有意义的,因为3
不是promise;没什么好等的。(实际上写await 3
是法律的的,但它并没有真正完成任何事情;你可以写3
。因此,
await user.click(...)
和await waitFor(...)
都很好,而await fireEvent.click(...)
不好的原因是user.click
和waitFor
都返回promise,而fireEvent.click
没有。fireEvent.click
只是调度事件并同步返回。(实际上,我也不确定user.click
是否做了任何 * 固有 * 异步的事情-它似乎不依赖于任何像fetch
这样的API-但可能测试库维护人员希望保持他们的选项开放,以防user.click
真实的需要支持异步的东西。但是waitFor
无论如何都必须是异步的,因为它的全部目的是每隔一段时间轮询一次回调,直到成功。1.我读到act / waitFor是等待DOM更新。我也读到渲染是同步的。我假设我不需要用act/waitFor Package Render,因为DOM总是在我单击或测试时更新?是这样吗?
因此,有两种“异步”:
act
来解决它。具体而言:如果你把这些东西 Package 在act(() => { ... })
中,那么React不会把微任务排队,而是把这些任务放在act
拥有的一个特殊队列中,act
将在返回之前执行这些任务。所以最终的结果是,从你的React组件的Angular 来看,任务仍然是异步的(例如,setState
立即返回,实际上没有改变任何东西),但从你的测试代码的Angular 来看,它现在是同步的(所有这些更新都发生在act
返回之前)。act
来完成这些操作,而是需要使用await
来等待它们完成。setState
的调用(这是非常常见的-用异步获取的信息更新UI),那么await
是不够的,因为setState
(故意)不返回一个你可以等待的promise,它只是在幕后排队一些更改。在这种情况下,您需要编写await act(async () => { ... })
。(act
有特殊的逻辑使此工作;它检测到回调返回了一个promise,并确保在自己的promise解析之前执行React的所有异步逻辑。现在你明白了,这个问题很容易回答:你不需要在
render
中使用act
,因为render
实际上在内部为你调用act
;您不需要将await
与render
一起使用,因为渲染不涉及任何真正的异步API。所以你可以直接使用render
。