NestJS测试文件中使用overrideGuard覆盖守卫不生效问题求助
问题排查
- 类名不一致问题:你在
AuthModule中通过APP_GUARD注册全局守卫时指定的useClass: IsAuthenticatedGuard,和你实际实现的守卫类MyGuard名称不匹配,请先确认是否是拼写错误,若你需要生效的就是MyGuard,先把AuthModule中的useClass改为MyGuard。 - 覆盖方式错误:通过
APP_GUARD令牌注册的全局守卫不属于路由/控制器级别的守卫,overrideGuard方法仅能匹配通过@UseGuards()装饰器注册的守卫,无法匹配到通过注入令牌注册的全局守卫,因此你的模拟逻辑没有生效。 - Mock调用顺序问题:你原测试代码中
canActivate.mockReturnValueOnce(true)直接写在describe块下,会在beforeEach的jest.resetAllMocks()之前执行,mock返回值会被清空,不会生效。
修复方案
直接替换APP_GUARD注入令牌对应的提供者即可完成全局守卫的模拟,修改后的测试代码如下:
import { APP_GUARD } from '@nestjs/core'; import { MyGuard } from '../src/modules/auth/guards/myfile-guard'; import { AppModule } from '../src/app.module'; import { INestApplication } from '@nestjs/common'; import { Test, TestingModule } from '@nestjs/testing'; import * as request from 'supertest'; describe('UserController (e2e)', () => { let app: INestApplication; const canActivate = jest.fn(() => true); beforeEach(async () => { const moduleFixture: TestingModule = await Test.createTestingModule({ imports: [AppModule], }) // 覆盖APP_GUARD令牌的提供者,替换为模拟对象 .overrideProvider(APP_GUARD) .useValue({ canActivate }) .compile(); app = moduleFixture.createNestApplication(); jest.resetAllMocks(); await app.init(); }); afterEach(async () => { await app.close(); }); describe('@Get()', () => { const requestUrl = '/users'; it('returns list of users', async () => { // 把mock返回值放到用例内部,避免被resetAllMocks清空 canActivate.mockReturnValueOnce(true); return request(app.getHttpServer()) .get(requestUrl) .expect(200); }); }); });
如果你的项目注册了多个全局守卫,只想覆盖MyGuard这一个,可使用以下写法精准匹配:
.overrideProvider({ provide: APP_GUARD, useClass: MyGuard, }) .useValue({ canActivate })
内容的提问来源于stack exchange,提问作者Paresh
相关产品推荐
相关产品推荐

