Jest测试axios登录函数时返回值为undefined问题排查
问题排查结论
userLogged始终返回undefined由两个核心问题导致:
- 测试用例中Axios mock的返回结构和真实请求逻辑不匹配:你的
loginUser封装里通过.then(r => r.data)提取Axios响应对象的data字段作为返回值,但测试时直接把用户信息对象作为axios.get的mock返回值,没有外层的data属性,导致r.data实际取到的是undefined - 多层catch吞掉了异常:
loginUser和handleLogin里的catch块都只打印控制台日志,既不抛出错误也不做显式失败处理,请求异常或者返回结构不符合预期时会静默返回undefined,没有明确报错提示
修复方案
1. 修正测试用例的mock返回结构
把Axios mock的返回值改成和真实响应一致的结构,外层包裹data字段:
// 原错误写法 // await axios.get.mockResolvedValue(userLogged); // 修正后 await axios.get.mockResolvedValue({ data: userLogged });
2. 优化请求封装的错误处理
不要在请求封装层静默吞掉错误,捕获后明确抛出,方便上层逻辑处理失败场景:
export default async function loginUser(username, password) { return await axios.get("http://localhost:8080/users/login", { headers: { "Content-Type": "application/json" }, params: { username: username, password: password } }).then(r => r.data) .catch(function (error){ console.log(error) throw error // 抛出异常,避免函数静默返回undefined }); }
3. 简化登录处理函数的异步逻辑
原逻辑混用await和.then链,可读性差且容易出现赋值时序问题,直接用try/catch配合await接收返回值即可,同时去掉重复的event.preventDefault()调用:
const handleLogin = async (event) => { event.preventDefault() setError(false) // 每次提交前重置错误状态 try { const userLogged = await loginUser(userNameState, passwordState) if (userLogged) { setUserInfo(userLogged) setAuthed(true) } else { setError(true); } } catch (err) { setError(true); } }
优化建议
- 登录接口涉及账号密码等敏感信息,不建议使用GET请求传参,参数会暴露在URL中,应改为POST请求将参数放在请求体传输
- 测试用例中点击登录按钮后,建议使用
waitFor等待异步状态更新完成后再执行断言,避免断言执行时机早于状态更新导致测试偶发失败:
await user.click(loginBtn) await waitFor(() => { expect(axios.get).toHaveBeenCalled() expect(setUserInfo).toHaveBeenCalledWith(userLogged) expect(setAuthed).toHaveBeenCalledWith(true) })
内容的提问来源于stack exchange,提问作者yassine-eluharani
相关产品推荐
相关产品推荐

