You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何mock模块级实例,验证myFunction是否调用了logger.log方法

错误原因分析

第一个方案失败原因

  • 业务代码中logger是在模块顶层作用域初始化的,当你导入被测试模块时,new Logger()就已经执行完成。你在测试用例内部才修改mockedLoggerClass.mockReturnValue,此时实例早已创建完毕,修改mock返回值不会生效。
  • 语法使用错误:mockReturnValue返回了箭头函数,而new关键字调用类预期返回实例对象,返回的函数不存在log方法自然无法被检测到调用;同时断言toBeCalled需要加括号写成toBeCalled(),否则只是判断属性是否存在,不会执行调用校验。

第二个方案失败原因

  • Jest会自动将所有jest.mock调用提升到模块最顶部执行,优先级高于所有普通变量声明。你定义loggerInstance的代码实际在jest.mock执行之后才运行,mock工厂函数访问loggerInstance时变量还未初始化,因此抛出引用错误。

可行解决方案

方案一:最简适配写法(适合绝大多数场景)

直接在mock工厂函数内定义mock方法,通过mock类的执行记录拿到已经生成的实例的log方法即可:

// 先mock Logger类,返回带mock log方法的实例
jest.mock('./logger', () => {
  return jest.fn(() => ({
    log: jest.fn()
  }))
})

// 按顺序导入依赖和被测试方法
import Logger from './logger'
import { myFunction } from './你的业务模块文件名'

// 业务代码导入时已经执行过一次new Logger,从mock的执行结果中拿到log的mock函数
const mockLog = (Logger as jest.Mock).mock.results[0].value.log

describe('测试myFunction', () => {
  // 每次用例执行前清空调用记录,避免用例之间互相干扰
  beforeEach(() => {
    mockLog.mockClear()
  })

  it('应该正确调用logger.log并传入参数Hello', () => {
    myFunction()
    expect(mockLog).toHaveBeenCalled()
    expect(mockLog).toHaveBeenCalledWith('Hello')
  })
})

方案二:支持自定义mock实现的写法

如果需要在不同测试用例中修改log方法的实现、返回值,可以用动态导出的方式避开变量提升问题:

// 提前定义mock方法并导出
export const mockUtils = {
  mockLog: jest.fn()
}

// mock工厂函数中通过require动态获取导出的mock方法
jest.mock('./logger', () => {
  return jest.fn(() => ({
    log: require('./当前测试文件的文件名').mockUtils.mockLog
  }))
})

import { myFunction } from './你的业务模块文件名'

describe('测试myFunction', () => {
  beforeEach(() => {
    mockUtils.mockLog.mockClear()
  })

  it('应该正确调用logger.log', () => {
    myFunction()
    expect(mockUtils.mockLog).toHaveBeenCalledWith('Hello')
  })

  it('支持自定义log方法的实现逻辑', () => {
    mockUtils.mockLog.mockImplementation(() => {
      // 自定义mock逻辑
    })
    myFunction()
    // 其他断言
  })
})

内容的提问来源于stack exchange,提问作者Nhu Trinh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 22:36:05