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

使用dataSource.getRepository时,getRepositoryToken模拟仓库失效的替代方案

解决TypeORM DataSource.getRepository的Mock问题

当你直接通过AppDataSource.getRepository()获取仓库实例时,getRepositoryToken确实无法生效——因为这个Token是配合@InjectRepository装饰器的依赖注入场景设计的。下面给你两种可行的解决方案,优先推荐第一种符合NestJS设计规范的做法:

方案一:通过依赖注入注入DataSource(推荐)

把全局的AppDataSource换成通过构造函数注入的DataSource实例,这样就能在测试中轻松mock它的getRepository方法。

修改UserService.ts

import { Injectable, Inject } from '@nestjs/common';
import { DataSource, Repository } from 'typeorm';
import { userEntity } from './user.entity';

export class UserService {
  private userRepository: Repository<userEntity>;

  constructor(
    // 注入DataSource实例
    @Inject(DataSource) private readonly dataSource: DataSource,
  ) {
    // 使用注入的dataSource获取仓库
    this.userRepository = this.dataSource.getRepository(userEntity);
  }
}

修改测试文件user.test.ts

import { Test } from '@nestjs/testing';
import { DataSource } from 'typeorm';
import { UserService } from './user.service';
import { userEntity } from './user.entity';

// 定义你的mock仓库实例
const mockUserRepository = {
  // 在这里添加你需要mock的方法,比如:
  findOne: jest.fn().mockResolvedValue({ id: 1, name: 'test' }),
  create: jest.fn().mockReturnValue({ name: 'new user' }),
};

beforeAll(async () => {
  const module = await Test.createTestingModule({
    providers: [
      UserService,
      {
        provide: DataSource,
        useValue: {
          // mock getRepository方法,根据传入的Entity返回对应的mock仓库
          getRepository: jest.fn((entity) => {
            if (entity === userEntity) {
              return mockUserRepository;
            }
            return {};
          }),
        },
      },
    ],
  }).compile();
});

方案二:直接Mock全局AppDataSource(不推荐,仅适配无法修改原有代码的场景)

如果不能改动服务里的代码,直接mock全局的AppDataSource对象,让它的getRepository返回你的mock仓库:

修改测试文件user.test.ts

import { Test } from '@nestjs/testing';
import { UserService } from './user.service';
import { AppDataSource } from './path-to-your-datasource-file'; // 替换成你的DataSource文件路径
import { userEntity } from './user.entity';

// 定义你的mock仓库实例
const mockUserRepository = {
  // 你的mock方法
};

// 提前mock全局的AppDataSource
jest.mock('./path-to-your-datasource-file', () => ({
  AppDataSource: {
    getRepository: jest.fn((entity) => {
      if (entity === userEntity) {
        return mockUserRepository;
      }
      return {};
    }),
  },
}));

beforeAll(async () => {
  const module = await Test.createTestingModule({
    providers: [UserService],
  }).compile();
});

为什么推荐方案一?

直接依赖全局AppDataSource会让服务和数据源实例强耦合,不仅测试麻烦,后续如果需要切换数据源或者做扩展也会受限。通过依赖注入的方式,既符合NestJS的设计原则,也让代码的可测试性和可维护性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 02:03:20