NestJS E2E测试报错:TypeError: metatype is not a constructor
解决NestJS全局守卫E2E测试Mock报错问题
错误原因
你遇到的TypeError: metatype is not a constructor是因为.useClass()方法要求传入类(构造函数),但你定义的mockAuthGuard是一个对象字面量(实例),不符合useClass的参数要求。
解决方案
方案1:用useValue替代useClass
直接将mock对象通过useValue注入,替换原有的ATGuard:
beforeAll(async () => { const mockAuthGuard: CanActivate = { canActivate: jest.fn(() => true) }; const moduleFixture: TestingModule = await Test .createTestingModule({ imports: [AppModule], }) // 替换useClass为useValue .overrideProvider(ATGuard).useValue(mockAuthGuard) .compile(); app = moduleFixture.createNestApplication<NestFastifyApplication>(new FastifyAdapter()); await app.init(); await app.getHttpAdapter().getInstance().ready(); });
方案2:直接覆盖全局APP_GUARD令牌
由于你的守卫是通过APP_GUARD全局注册的,也可以直接覆盖这个令牌的实现:
import { APP_GUARD } from '@nestjs/core'; // ... beforeAll(async () => { const mockAuthGuard: CanActivate = { canActivate: jest.fn(() => true) }; const moduleFixture: TestingModule = await Test .createTestingModule({ imports: [AppModule], }) .overrideProvider(APP_GUARD).useValue(mockAuthGuard) .compile(); // ... 后续初始化代码不变 });
为什么之前overrideGuard无效?
overrideGuard()方法主要用于覆盖控制器或方法级别通过@UseGuard()装饰器注册的守卫,而你是在AppModule中通过APP_GUARD令牌全局注册的守卫,所以需要用overrideProvider()来处理。
验证测试
修改后重新运行测试,mockAuthGuard的canActivate会始终返回true,/health接口应该返回200状态码,符合预期。
内容的提问来源于stack exchange,提问作者Jackson Fleming
相关产品推荐
相关产品推荐

