如何从NestFastifyApplication获取Repository或当前TypeORM实例?
你不需要从app实例上提取TypeORM相关实例,直接通过你已经编译生成的测试模块实例module就能拿到应用内已经初始化完成的数据库连接和Repository,完全不需要重复新建连接。
1. 提取TypeORM数据库连接实例(DataSource)
TypeORM 0.3.x版本后统一用DataSource代表数据库连接实例(旧版本对应Connection),直接通过module.get()方法跨模块获取即可:
import { DataSource } from 'typeorm'; // 注意加 { strict: false } 让Nest遍历整个模块依赖树查找provider const dataSource = module.get(DataSource, { strict: false });
拿到DataSource后你可以直接执行所有数据库操作,比如测试结束后清理测试数据:
afterAll(async () => { // 清空所有实体对应表的测试数据示例 const entities = dataSource.entityMetadatas; for (const entity of entities) { const repo = dataSource.getRepository(entity.name); // 注意如果有外键约束,注意调整清空顺序,或者用query执行TRUNCATE级联清空 await repo.clear(); } await app.close(); });
2. 提取指定实体对应的Repository
如果只需要拿单个实体的Repository做校验,可以用@nestjs/typeorm提供的getRepositoryToken生成注入token,再从module中获取:
import { getRepositoryToken } from '@nestjs/typeorm'; // 替换成你自己的实体类 import { User } from '../src/user/entities/user.entity'; const userRepository = module.get( getRepositoryToken(User), { strict: false } ); // 测试逻辑中可以直接用userRepository做数据库查询断言
如果你配置了多数据库连接,给getRepositoryToken和get方法传入第二个参数指定连接名即可,比如getRepositoryToken(User, 'db_connection_2')。
你调用app.select(TypeOrmModule)报错的原因
select()方法只能匹配模块树中存在的模块实例,而你在AppModule中通过TypeOrmModule.forRoot()/forRootAsync()注册的是动态生成的模块实例,和你直接传入的TypeOrmModule类引用不是同一个上下文对象,所以Nest会提示找不到模块。
实际上你完全不需要调用select方法,只要在调用module.get()时传入{ strict: false },Nest就会自动遍历整个模块依赖树查找你需要的provider,包括TypeORM注册的DataSource、所有实体Repository,和应用运行时内部用的实例完全一致,不会重复创建连接。
内容的提问来源于stack exchange,提问作者Daniel Parra Gonzalez

