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

无法Mock TypeORM DataSource,求Jest中更优Mock方案

在Jest中Mock TypeORM DataSource的正确方式

错误原因分析

你遇到的TypeError: Cannot set property DataSource of [object Object] which has only a getter,是因为typeorm.DataSource是TypeORM导出的只读类,只能通过Jest的jest.mock机制来Mock,无法直接赋值覆盖。加上你的AppService是直接导入了预实例化的connectDB对象,所以Mock的核心要针对这个导出的实例,而非DataSource类本身。

优化方案一:直接Mock数据库配置模块

针对你当前的代码结构,最直接的方式是Mock../config/db_connection模块的导出,让它返回一个模拟的DataSource实例:

import { AppService } from '../services';
import connectDB from '../config/db_connection';

// Mock整个db_connection模块
jest.mock('../config/db_connection', () => ({
  __esModule: true,
  default: {
    manager: {
      find: jest.fn().mockResolvedValue([]), // 可预设测试用返回值
    },
  },
}));

describe("Tests for AppService", () => {
  it("should call getServices and trigger manager.find", async () => {
    const appService = new AppService();
    await appService.getServices(1);
    
    // 断言find方法被调用
    expect(connectDB.manager.find).toHaveBeenCalled();
    // 可选:断言调用参数是否符合预期
    expect(connectDB.manager.find).toHaveBeenCalledWith(
      expect.any(Function),
      { relations: { service: true } }
    );
  });
});

优化方案二:结合NestJS依赖注入(推荐)

如果你的项目基于NestJS,更优雅的方式是通过依赖注入注入DataSource,而非直接导入实例,这样Mock会更灵活:

修改AppService代码

import { Injectable } from '@nestjs/common';
import { DataSource, Like } from 'typeorm';
import { services } from '../entity/services';
import { versions } from '../entity/versions';

@Injectable()
export class AppService {
  // 通过构造函数注入DataSource
  constructor(private readonly dataSource: DataSource) {}

  public getServices(id: number): Promise<versions[]> {
    return this.dataSource.manager.find(versions, {
      relations: {
        service: true,
      },
    });
  }
}

测试文件代码

import { Test } from '@nestjs/testing';
import { AppService } from '../services';
import { DataSource } from 'typeorm';

describe("Tests for AppService", () => {
  let appService: AppService;
  let mockDataSource: Partial<DataSource>;

  beforeEach(async () => {
    // 构建模拟的DataSource实例
    mockDataSource = {
      manager: {
        find: jest.fn().mockResolvedValue([]),
      },
    };

    // 创建测试模块,注入Mock的DataSource
    const moduleRef = await Test.createTestingModule({
      providers: [
        AppService,
        {
          provide: DataSource,
          useValue: mockDataSource,
        },
      ],
    }).compile();

    appService = moduleRef.get<AppService>(AppService);
  });

  it("should call getServices and trigger manager.find", async () => {
    await appService.getServices(1);
    expect(mockDataSource.manager.find).toHaveBeenCalled();
  });
});

关键注意点

  • 不要直接修改TypeORM导出的只读类(比如typeorm.DataSource),必须用jest.mock或依赖注入的方式Mock依赖。
  • 如果是NestJS项目,优先使用依赖注入,这会让测试更符合框架设计,也更容易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 11:15:30