目前,我正在学习如何使用 React 进行单元测试。但是,我想用 TypeScript 来学习它,所以本课程没有涵盖 TS 中出现的大多数错误。
我有一个使用 Mock Service Worker (msw) 配置的简单测试功能:
fit("sends username, email and password to backend after clicking the button", async () => {
let requestBody;
const server = setupServer(
rest.post("/api/1.0/users", (req, res, ctx) => {
requestBody = req.body;
return res(ctx.status(200));
})
);
server.listen();
setupAll(); // Gets the elements on the page (like button)
userEvent.click(button);
await new Promise((resolve) => setTimeout(resolve, 250));
expect(requestBody).toEqual({
username: "LegacyUser",
email: "legacy@user.com",
password: "P455w0rd!",
});
});
从理论上讲,这“有效”(它在测试列表中显示为通过),但在它上面会发生错误,例如:
console.error
Warning: An update to SignUpPage inside a test was not wrapped in act(...).
When testing, code that causes React state updates should be wrapped into act(...):
act(() => {
/* fire events that update state */
});
/* assert on the output */
userEvent.click(button)
因此,当我换行时act(() => userEvent.click(button))
,它会一直显示此错误消息。
点击 userEvent 触发一个 onSubmit 处理程序:
const formSubmitHandler = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
const { username, email, password } = formEntries;
setIsApiInProgress(true);
axios
.post("/api/1.0/users", {
username,
email,
password,
})
.then((response) => {
if (response.status >= 200 && response.status < 300) {
setIsSignUpSuccessfull(true);
// console.log("OK", response.data);
return response.data;
}
throw new Error(response.status.toString());
})
.catch(({ response }) => {
console.log("CATCH", response);
})
.finally(() => {
setIsApiInProgress(false);
});
};
我在这里做错了什么?另外,有没有办法在不使用超时的情况下等待已解决的承诺?这种方式感觉有点hacky。