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

如何使用Jest mock MongoDB客户端的事件监听器?

实现方案

核心思路是在mock connect 方法的返回值时,保留事件回调的存储和触发能力,具体实现如下:

完整测试代码

const { ServiceBroker } = require('moleculer'); // 注意提前引入对应ServiceBroker依赖

test('should write error to console when mongo client emits error event', async () => {
  //  mock console.error 用于后续断言
  const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
  const broker = new ServiceBroker({ logger: false });
  broker.loadService(`${process.cwd()}/index.js`);
  const services = broker.services.filter(
    (service) => service.fullName === 'mongo'
  );

  // 存储事件回调的对象
  const eventCallbacks = {};
  const connectSpy = jest.spyOn(services[0].client, 'connect');
  connectSpy.mockResolvedValue({
    db: jest.fn().mockReturnValue({
      collection: jest.fn(),
    }),
    // 实现on方法,存储对应事件的回调
    on: jest.fn((eventName, callback) => {
      if (!eventCallbacks[eventName]) {
        eventCallbacks[eventName] = [];
      }
      eventCallbacks[eventName].push(callback);
    }),
    // 实现emit方法,触发对应事件的所有回调
    emit: jest.fn((eventName, ...args) => {
      if (eventCallbacks[eventName]) {
        eventCallbacks[eventName].forEach(cb => cb(...args));
      }
    })
  });

  await broker.start();
  expect(connectSpy).toHaveBeenCalled();
  // 验证error事件已经被注册
  expect(connectSpy.mock.results[0].value.on).toHaveBeenCalledWith('error', expect.any(Function));

  // 模拟触发error事件
  connectSpy.mock.results[0].value.emit('error');

  // 断言控制台输出符合预期
  expect(consoleErrorSpy).toHaveBeenCalledWith('MongoDB error');

  // 恢复spy避免影响其他测试
  consoleErrorSpy.mockRestore();
});

实现说明

  • 在mock的connect返回值中新增eventCallbacks对象用来存储所有注册的事件回调
  • 重写on方法,每当有事件被注册时就把对应的回调存到eventCallbacks中
  • 新增emit方法,调用时会取出对应事件的所有回调执行,以此模拟Mongo客户端的事件触发逻辑
  • 通过监听console.error的调用来验证错误日志是否正常输出

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:45:00