han*_*ruh 11 javascript asynchronous typescript reactjs react-testing-library
我有一个通过回调更改状态的异步方法:
class Demo{
callback: () => void;
async triggerCallback() {
this.callback();
}
}
Run Code Online (Sandbox Code Playgroud)
此回调用于隐藏/显示元素:
const DemoComponent: React.FunctionComponent<Props> = ({Demo}) =>{
const [show, setShow] = useState(false);
const changeStateCallback = () => {
setState(true);
}
useEffect(() =>{
Demo.callback = changeStateCallback;
}, []);
return(
<>
{show && <p>Foo</p>}
</>
)
};
Run Code Online (Sandbox Code Playgroud)
我现在想测试这个,我仍在学习使用 Jest 和 React 测试库进行测试,所以一开始我有:
it("test", async () => {
const Demo = new Demo();
render(<DemoComponent Demo={Demo}/>);
await Demo.triggerCallback();
expect(screen.queryByText("Foo")).toBeTruthy();
}
Run Code Online (Sandbox Code Playgroud)
这失败了,因为它抱怨 Demo.triggerCallback(); 必须包含在 act() 中:
测试时,导致 React 状态更新的代码应包装到 act(...) 中:
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();
}
Run Code Online (Sandbox Code Playgroud)
它再次失败,说我无法使行为异步:
警告:传递给 ReactTestUtils.act(...) 函数的回调不得返回任何内容。
看起来您编写了 ReactTestUtils.act(async () => ...),或者从传递给它的回调返回了一个 Promise。不支持将异步逻辑放入 ReactTestUtils.act(...) 中。
经过对文档和谷歌的一些研究,我发现了这个 waitFor() 方法,但与期望一起使用,例如:
await waitFor(() => {
expect(getByText('1')).toBeInTheDocument();
});
Run Code Online (Sandbox Code Playgroud)
但为此,我将 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();
}
Run Code Online (Sandbox Code Playgroud)
并且测试通过了!现在……这是正确的吗?只是因为它有效,我不确定解决方案,所以希望得到一些反馈。我觉得我在做一些非法的事情,因为我只能找到 waitFor() 和 Expect() 的例子,而没有其他的。