NestJS单元测试中TypeORM关联未加载导致类型不匹配问题
解决方案
1. 不要修改Service返回类型为Partial/DeepPartial
TypeORM给find()标注返回Organisation[],是因为从实体定义的角度,knowledgeDataPools是实体的一部分——只是默认查询不会主动加载关联数据。改成Partial会模糊实体的结构定义,后续业务代码中无法区分“未加载的关联”和“真正的可选字段”,反而增加维护成本。
2. 测试中的两种修复方式
方式一:补全mock数据的必填字段
直接给测试的result添加空数组的knowledgeDataPools,让它符合Organisation类型要求:
const result = [ { id: 1, name: 'Example', knowledgeDataPools: [] }, ];
方式二:用类型断言临时绕过(仅测试场景使用)
如果不想添加空数组,可在测试中用类型断言告知TypeScript该数据符合Organisation类型:
jest.spyOn(organisationService, 'findAll').mockResolvedValue(result as Organisation[]);
3. 理解TypeORM的关联加载逻辑
TypeORM默认不会自动加载@OneToMany这类关联关系,需显式指定才会加载:
如果业务逻辑需要返回包含knowledgeDataPools的组织数据,可在find()中添加relations选项:
findAll(): Promise<Organisation[]> { return this.organsiationRepository.find({ relations: ['knowledgeDataPools'] }); }
此时返回的对象会包含完整的knowledgeDataPools字段,类型匹配问题也会解决。
4. 进阶方案:用DTO规范返回结构
如果API本来就不需要返回knowledgeDataPools,可以定义DTO(数据传输对象),只包含对外暴露的字段,再在Service中完成实体到DTO的转换:
// organisation.dto.ts export class OrganisationDTO { id: number; name: string; } // 修改OrganisationService的findAll方法 findAll(): Promise<OrganisationDTO[]> { return this.organsiationRepository.find().then(orgs => orgs.map(org => ({ id: org.id, name: org.name })) ); }
这样测试中的mock数据就能和DTO类型完全匹配,不会再出现类型错误。
内容的提问来源于stack exchange,提问作者Doku
相关产品推荐
相关产品推荐

