使用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
相关产品推荐
相关产品推荐

