React结合Axios测试时出现TypeError: Cannot read property 'then' of undefined
问题原因及解决方案
你遇到的测试环境下httpService.fetchData返回undefined的问题,主要有以下几类常见原因,按出现概率从高到低排序:
- mock的对象和实际调用的对象不匹配
这是最常见的原因,检查两个点:- 测试文件和Header组件中导入
HttpService的路径是否完全一致,包括大小写、相对路径层级,路径拼写错误会导致两个文件拿到的不是同一个实例对象,你的mock只会作用于测试文件导入的对象,组件实际调用的还是原生方法 - 检查
HttpService的导出导入方式是否匹配:如果是export default HttpService导出,就必须用import HttpService from 'xxx'导入;如果是export const HttpService导出,就必须用import { HttpService } from 'xxx'导入,两者不匹配也会导致mock失效。
当mock完全失效时,测试环境如果没有配置全局axios的mock返回值,原生fetchData里的axios.get就会返回undefined,触发报错。
- 测试文件和Header组件中导入
- mockImplementationOnce已经被提前消耗
mockImplementationOnce的规则是只会生效一次,如果你在当前测试逻辑触发前,已经有其他操作调用过一次fetchData,到你要测试的场景时mock已经失效,会直接调用原生方法,没有配置返回的情况下就会返回undefined。如果需要所有调用都走mock逻辑,可以把mockImplementationOnce换成mockImplementation。 - mock执行时机晚于组件初始化
如果你测试代码的执行顺序是「先渲染Header组件」再「执行jest.spyOn mock逻辑」,那么组件在初始化时已经拿到了未被mock的fetchData方法引用,后续的mock不会替换已经绑定的引用,导致实际调用的还是原生方法。调整执行顺序,先完成mock再渲染组件即可解决。
额外提示:你当前的mock返回结构不符合axios的规范,
axios.get返回的Promise直接包裹响应对象,不需要调用json()方法(json()是原生Fetch API的逻辑)。解决返回undefined的问题后,你可以把mock返回值调整为Promise.resolve({ data: MockResponseData }),和实际axios返回结构对齐,避免后续逻辑报错。
内容的提问来源于stack exchange,提问作者Lajos Bela
相关产品推荐
相关产品推荐

