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

模拟AMQPClient父类后调用子类方法Jest抛出is not a function错误

RabbitMQ服务Jest测试报错解决方案

问题场景

实现了继承自AMQPClient的RabbitMqService类,代码如下:

import { environment } from '@Utils/environment'
import { AMQPChannel, AMQPClient } from '@cloudamqp/amqp-client'
import { AMQPBaseClient } from '@cloudamqp/amqp-client/types/amqp-base-client'

export class RabbitMqService extends AMQPClient {
  public connection?: AMQPBaseClient
  private lastDispatch: number = Date.now()

  public constructor() {
    super(environment.rabbitMqUrl)
    this.connection = undefined
  }

  public async connectToInstance(): Promise<AMQPBaseClient> {
    this.connection = await this.connect()
    return this.connection
  }
}

编写Jest测试时尝试mock父类AMQPClient,测试代码如下:

import { RabbitMqService } from '../rabbit-mq.service'

jest.mock('@cloudamqp/amqp-client', () => {
  return {
    ...jest.requireActual('@cloudamqp/amqp-client'),
    AMQPClient: jest.fn().mockImplementation(() => {
      return {
        connect: jest.fn().mockReturnThis()
      }
    })
  }
});

it('Should establish connection successfully', async () => {
  const rabbitMqService = new RabbitMqService();
  await rabbitMqService.connectToInstance()
})

运行测试时抛出is not a function错误,当前Jest配置:

import type { Config } from '@jest/types'

const config: Config.InitialOptions = {
  verbose: true,
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  },
  automock: true,
  moduleNameMapper: {
    '^Root/(.*)$': '<rootDir>/src',
    '^@Assets/(.*)$': '<rootDir>/src/assets/$1',
    '^@Data/(.*)$': '<rootDir>/src/data/$1',
    '^@Events/(.*)$': '<rootDir>/src/events/$1',
    '^@Guards/(.*)$': '<rootDir>/src/guards/$1',
    '^@Interceptors/(.*)$': '<rootDir>/src/interceptors/$1',
    '^@Services/(.*)$': '<rootDir>/src/services/$1',
    '^@Types/(.*)$': '<rootDir>/src/types/$1',
    '^@Utils/(.*)$': '<rootDir>/src/utils/$1'
  }
}
export default config

报错原因

  1. automock冲突:开启automock: true后,Jest会自动mock所有依赖模块,和手动编写的jest.mock逻辑冲突,导致父类AMQPClient的mock实现异常。
  2. mock实现错误:当前mock的AMQPClient返回的对象中,connect方法用mockReturnThis()返回子类实例,但connect实际应该返回AMQPBaseClient类型实例,类型不匹配导致调用时报错。
  3. 继承类mock不完整:直接mockAMQPClient构造函数返回对象,没有正确模拟父类的原型链,导致子类继承的方法调用异常。

解决步骤

1. 修改Jest配置,关闭automock

在jest.config.ts中把automock: true改为false:

import type { Config } from '@jest/types'

const config: Config.InitialOptions = {
  verbose: true,
  transform: {
    '^.+\\.tsx?$': 'ts-jest'
  },
  automock: false, // 关闭自动mock
  moduleNameMapper: {
    '^Root/(.*)$': '<rootDir>/src',
    '^@Assets/(.*)$': '<rootDir>/src/assets/$1',
    '^@Data/(.*)$': '<rootDir>/src/data/$1',
    '^@Events/(.*)$': '<rootDir>/src/events/$1',
    '^@Guards/(.*)$': '<rootDir>/src/guards/$1',
    '^@Interceptors/(.*)$': '<rootDir>/src/interceptors/$1',
    '^@Services/(.*)$': '<rootDir>/src/services/$1',
    '^@Types/(.*)$': '<rootDir>/src/types/$1',
    '^@Utils/(.*)$': '<rootDir>/src/utils/$1'
  }
}
export default config

2. 修正AMQPClient的mock实现

确保mock的父类构造函数正确模拟原型链,并且connect方法返回符合AMQPBaseClient类型的模拟对象:

import { RabbitMqService } from '../rabbit-mq.service'
import { AMQPBaseClient } from '@cloudamqp/amqp-client/types/amqp-base-client'

// 模拟AMQPBaseClient实例
const mockAMQPBaseClient = {} as AMQPBaseClient

jest.mock('@cloudamqp/amqp-client', () => {
  // 获取真实模块的类型定义,避免类型报错
  const actual = jest.requireActual('@cloudamqp/amqp-client')
  return {
    ...actual,
    AMQPClient: jest.fn().mockImplementation(() => {
      return {
        // 让connect返回模拟的AMQPBaseClient实例
        connect: jest.fn().mockResolvedValue(mockAMQPBaseClient)
      }
    })
  }
});

it('Should establish connection successfully', async () => {
  const rabbitMqService = new RabbitMqService();
  const connection = await rabbitMqService.connectToInstance()
  
  // 验证connect方法被调用
  expect(rabbitMqService.connect).toHaveBeenCalled()
  // 验证connection返回正确的模拟实例
  expect(connection).toBe(mockAMQPBaseClient)
})

3. 处理类型提示(可选)

如果遇到类型报错,可以用类型断言明确mock对象的类型,或者在测试文件顶部添加/* eslint-disable @typescript-eslint/no-explicit-any */临时忽略类型检查。

验证

运行Jest测试,此时应该可以正常执行,不再抛出is not a function错误,并且能验证connect方法的调用和返回值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 06:09:24