NestJS TypeORM InjectRepository 无法读取未定义的属性“原型”

Posted

技术标签:

【中文标题】NestJS TypeORM InjectRepository 无法读取未定义的属性“原型”【英文标题】:NestJS TypeORM InjectRepository Cannot read property 'prototype' of undefined 【发布时间】:2019-07-27 08:02:21 【问题描述】:

尝试进行单元测试。 出现以下错误:

TypeError: 无法读取未定义的属性“原型”

导出类 UserService

constructor(@InjectRepository(User) 私有只读 userRepository: 存储库 )

spec.ts:

describe('AuthController', () => 
let authController: AuthController;
let authService: AuthService;
let mockRepository = 

;
beforeEach(async () => 
    const module = await Test.createTestingModule(
        imports: [
            TypeOrmModule.forFeature([User]),
        ],
        controllers: [AuthController],
        providers: [AuthService, 
            provide: getRepositoryToken(User),
            useValue: mockRepository
        ]
    ).compile()
    authService = module.get<AuthService>(AuthService);
    authController = module.get<AuthController>(AuthController)
);

有人可以分享解决方案吗?

更多信息

所以typeorm 似乎有问题

beforeEach(async () => 
    const module = await Test.createTestingModule(

    ).compile()
    authService = module.get<AuthService>(AuthService);
    authController = module.get<AuthController>(AuthController)
);

使用此代码,我得到了完全相同的错误。所以唯一的问题是在这个测试模块中添加typeorm

所以它因为依赖而失败:AuthController->AuthService->UserService->TypeORM

顺便说一句,刚刚使用带有 Postman 的 API 检查了UserService,它工作正常。

还是没有结果:

 module = await Test.createTestingModule(
        controllers: [AuthController],
        components: [
            
                provide: AuthService,
                useValue: 
            ,
            
                provide: UserService,
                useValue: 
            ,
            
                provide: getRepositoryToken(User),
                useValue: 
            
        ],
        providers: [
            
                provide: AuthService,
                useValue: 
            ,
            
                provide: UserService,
                useValue: 
            ,
            
                provide: getRepositoryToken(User),
                useValue: 
            
        ]
    ).compile()
    this.authController = module.get<AuthController>(AuthController)

还有

class AuthServiceMock 
    logIn(userName) 
        return  id:100, isDeleted:false, login:"login", password:"password";
    

    signUp() 
        return  expireIn: 3600, token:"token" ;
    


describe('AuthController', () => 
let module: TestingModule;
let authController: AuthController;
let authService: AuthService;

beforeEach(async () => 
    module = await Test.createTestingModule(
        controllers: [AuthController],
        components: [

        ],
        providers: [
            
                provide: AuthService,
                useClass: AuthServiceMock
            ,
        ]
    ).compile()
    this.authController = module.get<AuthController>(AuthController)
);

【问题讨论】:

你解决了吗?我有同样的问题 @alex88 是的。我重新创建了项目并将所有旧文件复制到新文件。似乎是一些 typeorm 错误。 【参考方案1】:

我花了好几个小时才弄明白,它确实有效

 async findAll() 
    
    return await this.userRepository.createCursor(this.userRepository.find()).toArray();
  

【讨论】:

【参考方案2】:

我查看了您在 Kim Kern (https://github.com/rankery/wof-server) 下的评论中提供的项目

您正在使用桶文件 (src/user/index.ts),导出 UserModule

export * from './user.module';

我猜你稍后会使用这个桶文件来导入模块。

现在,每次导入桶文件的内容时,都会执行您的src/user/user.module.ts 构建版本中包含的代码,其中包括UserModule 类的修饰,这反过来将使Typeorm 尝试构建一个存储库,这会导致错误。

您应该从 src/user/index.ts 中删除此导出(或直接删除文件)并修复此删除导致的损坏导入,它应该可以工作。

【讨论】:

为了让更多的用户受益于您的回答,请您提供更多的解释。 你救了我!【参考方案3】:

当您导入TypeOrmModule.forFeature(...) 时,您还必须导入TypeOrmModule.forRoot(...)。但在单元测试中,您可能不想使用数据库,而是模拟所有依赖项。

您的控制器不应直接访问数据库,这就是服务的用途。所以如果你想测试你的控制器并且它只注入服务,你应该只声明一个AuthService 模拟而不导入任何东西:

const module = await Test.createTestingModule(
    controllers: [AuthController],
    providers: [
        provide: AuthService,
        useValue: authServiceMock
    ]
).compile()

如果您想测试您的 AuthService 并且它只注入存储库,请声明您的 mockRepository 并保留其他所有内容。

【讨论】:

UserService 注入存储库,AuthService 注入 UserService。我尝试了你的代码,但仍然遇到同样的错误。 奇怪,typeorm 根本不参与控制器测试。错误的堆栈跟踪是什么,它指向哪里? 看看这个测试以供参考:github.com/kiwikern/shassi-nest/blob/master/src/auth/… 它指向 @InjectRepository(User) at Object.getRepositoryToken 这真的很奇怪。当您使用模拟对AuthControllerAuthService 进行单元测试时,实际的UserService 应该永远被实例化。【参考方案4】:

我刚刚将 User 实体传递给 Repository,它就可以工作了。

@Injectable()
export class UserService 
    constructor(
        @InjectRepository(User)
        private readonly userRepository: Repository<User>
    )  


从此处查看文档:https://docs.nestjs.com/techniques/database。他们有很好的文档。

【讨论】:

以上是关于NestJS TypeORM InjectRepository 无法读取未定义的属性“原型”的主要内容,如果未能解决你的问题,请参考以下文章

过滤从查询参数传递的数组。 NestJS,TypeORM

NestJS + TypeORM 中的 JoinTable 问题

NestJS + TypeORM:使用两个或更多数据库?

播种时NestJS中的TypeOrm:RepositoryNotFoundError

在 Nestjs 中注入 Tree Typeorm 存储库

Nestjs 与自定义存储库中的 Typeorm 事务