提问人:hanuruh 提问时间:7/13/2021 更新时间:6/26/2023 访问量:7090
React 测试库:waitFor vs act
React Testing Library: waitFor vs act
问:
我有一个异步方法,可以通过回调更改状态:
class Demo{
callback: () => void;
async triggerCallback() {
this.callback();
}
}
此回调用于隐藏/显示元素:
const DemoComponent: React.FunctionComponent<Props> = ({Demo}) =>{
const [show, setShow] = useState(false);
const changeStateCallback = () => {
setState(true);
}
useEffect(() =>{
Demo.callback = changeStateCallback;
}, []);
return(
<>
{show && <p>Foo</p>}
</>
)
};
我现在想测试这个,我仍在学习使用 Jest 和 React 测试库进行测试,所以起初我有:
it("test", async () => {
const Demo = new Demo();
render(<DemoComponent Demo={Demo}/>);
await Demo.triggerCallback();
expect(screen.queryByText("Foo")).toBeTruthy();
}
这失败了,因为它抱怨 Demo.triggerCallback();必须包装在 act() 中:
测试时,导致 React 状态更新的代码应包装到 act(...):
行为(() => { /* 更新状态的触发事件 / }); / 在输出上置位 */
我用 async/await 规则做了什么:
it("test", async () => {
const Demo = new Demo();
render(<DemoComponent Demo={Demo}/>);
await act( async () =>{
await Demo.triggerCallback();
};
expect(screen.queryByText("Foo")).toBeTruthy();
}
它再次失败,说我无法使行为异步:
警告:传递给 ReactTestUtils.act(...) 函数的回调必须 不返回任何内容。
看起来你写了 ReactTestUtils.act(async () => ...),或者 从传递给它的回调中返回一个 Promise。把 不支持 ReactTestUtils.act(...) 中的异步逻辑。
在文档和谷歌中进行了一些研究后,我发现了这个 waitFor() 方法,但与 expect 一起,例如:
await waitFor(() => {
expect(getByText('1')).toBeInTheDocument();
});
但为了它,我将 act() 替换为 waitFor(),因为它是我在 react 测试库中找到的为数不多的异步方法之一。最后的样子(为了以防万一,我把它包装在一个try/catch中):
it("test", async () => {
const Demo = new Demo();
render(<DemoComponent Demo={Demo}/>);
try {
await waitFor( async () =>{
await Demo.triggerCallback();
};
} catch(e) {
fail("Test failed": + e);
}
expect(screen.queryByText("Foo")).toBeTruthy();
}
测试通过了!现在。。。这是正确的吗?仅仅因为它有效,我不确定解决方案,所以希望对此提供一些反馈。我觉得我在做一些非法的事情,因为我只能找到带有 expect() 的 waitFor() 示例,而没有别的。
答: 暂无答案
评论
DemoComponent