Jest模拟getEnvironment返回undefined及导入函数模拟差异咨询
问题解答
1. getEnvironment模拟失效导致brokers为undefined的原因
- 错误使用异步模拟方法:你为
getEnvironment调用了mockResolvedValue方法,这个方法会让函数返回Promise对象,而你的业务代码是同步调用getEnvironment()作为kafkaBrokers的属性索引,相当于用Promise对象当key去取对象属性,自然得到undefined。如果getEnvironment本身是同步函数,应该替换为mockReturnValue('testBrokers')。 - 未模拟
kafkaBrokers配置:你的测试代码完全没有mock../config/kafkaConfig模块,业务代码中用到的kafkaBrokers是加载的真实配置文件,就算getEnvironment返回了正确的testBrokers字符串,只要真实配置里没有对应testBrokers的属性,取值还是undefined。 - 模块初始化时机问题:你测试的kafka客户端是在模块顶层直接初始化的,也就是执行
require('./client')的时候就会立即执行new Kafka的逻辑,要保证所有mock逻辑(包括getEnvironment、kafkaConfig的模拟)都在require('./client')之前完成,否则初始化的时候mock还没生效。 - 如果
getEnvironment本身就是异步函数,那你的业务代码写法本身存在问题:顶层代码无法直接await异步函数的返回值,直接调用拿到的永远是Promise对象,需要把kafka客户端的初始化封装为异步工厂函数,调用时await拿到结果再使用。
2. 模拟默认导入和命名导入的差异
默认导入和命名导入的模拟方式存在明显差异,核心原因是两者的导出结构不同,Jest模拟时需要匹配对应的导出结构才能生效,写法错误会导致mock不生效、取值为undefined等问题。
3. 两种导入的模拟示例
先准备两个测试模块
命名导出模块 utils.js
// CommonJS 命名导出写法 exports.getNum = () => 1 exports.getName = () => 'test'
默认导出模块 calc.js
// CommonJS 默认导出写法(整个导出为一个函数) module.exports = (a, b) => a + b
命名导入的模拟方式
// 命名导入 const { getNum } = require('./utils') // 模拟时要匹配命名导出的结构,每个导出属性单独声明mock jest.mock('./utils', () => ({ getNum: jest.fn().mockReturnValue(100), getName: jest.fn().mockReturnValue('mockName') })) console.log(getNum()) // 输出 100
默认导入的模拟方式
// 默认导入 const calc = require('./calc') // 模拟时直接返回对应的mock对象/函数即可 jest.mock('./calc', () => jest.fn().mockReturnValue(10)) console.log(calc(1,2)) // 输出 10
如果是ES Module语法的默认导出,模拟时需要单独处理default属性:
// ES Module 默认导出模拟 jest.mock('./calc', () => ({ default: jest.fn().mockReturnValue(10) }))
内容的提问来源于stack exchange,提问作者amarnath harish
相关产品推荐
相关产品推荐

