Jest测试Mocked Fetch API返回undefined的问题排查与解决
问题描述
我在React/TS项目中封装了如下通用FetchService:
/* Generic Fetch Service */ const FetchService = { call: async (url:string) => { try { return await fetch(url) .then((res) => res.json()) .then((data) => { data.response}); } catch (e) { throw Error(e); } } } export default FetchService
编写的测试代码如下:
import FetchService from "../../services/Fetch.service"; it("should call Fetch Service", async () => { const val = { json: async () => [{ data: { response: "aaa" } }] }; window.fetch = jest.fn().mockImplementationOnce((url) => { if (url === "localhost") { return Promise.resolve(val); } }); const data = await FetchService.call("localhost"); expect(data).toBe(undefined); });
测试成功覆盖了成功流程,但返回值为undefined,不是测试中Mock的response数据。如果在服务代码的data.response位置打印日志,能正常输出测试中Mock的'aaa'值。
错误原因
- 核心问题出在FetchService的Promise链式调用逻辑:最后一个
then的回调使用了花括号包裹逻辑,但没有显式添加return语句,{ data.response }没有返回值,导致整个异步调用最终返回undefined。如果要保留花括号写法,需要补全return:then((data) => { return data.response }),也可以去掉花括号用箭头函数简写:then((data) => data.response)。 - 测试用例的Mock数据格式存在问题:原始
val的json()方法返回的是数组结构,还多嵌套了一层data字段,和服务代码中直接取data.response的逻辑不匹配。
修复方案
修正后的FetchService代码:
/* Generic Fetch Service */ const FetchService = { call: async (url: string) => { try { const response = await fetch(url); const data = await response.json(); console.log(data.response, "data111"); return data.response; } catch (err) { throw err; } }, }; export default FetchService;
修正后的测试代码:
const val = { json: async () => { return { response: "aaa" }; }, }; it("should call Fetch Service", async () => { window.fetch = jest.fn().mockImplementationOnce((url) => { if (url === "localhost") { return val; } }); const data = await FetchService.call("localhost"); expect(data).toBe("aaa"); });
内容的提问来源于stack exchange,提问作者Ruben Marcus
相关产品推荐
相关产品推荐

