Search code examples
typescriptnestjse2e-testing

How to override APP_GUARD in E2E tests


I'm writing E2E tests for my NestJS project and I bumped into one issue I could not solve.

This is my setup fragment

const moduleFixture: TestingModule = await Test.createTestingModule({
  imports: [AppModule], // AppModule imports AuthModule
})
  .overrideProvider(APP_GUARD) // Not working
  .useClass(MockedAuthGuard)
  .compile();

app = moduleFixture.createNestApplication<NestExpressApplication>();

The goal is to use MockedAuthGuard instead of real AuthGuard in my tests.

The problem is that it has no effect. It still hits a real class instead of my mock version.

What I tried is to modify my module like so

@Module({
  imports: [],
  providers: [
    {
      provide: APP_GUARD,
      useClass: Env.isE2E ? MockedAuthGuard : AuthGuard,
    },
  ],
})
export class AuthModule {}

And now it works, but I don't like this part Env.isE2E ? MockedAuthGuard : AuthGuard. I want to keep it clean and only override it in E2E tests.

What am I missing here? How can I make it work by using overrideProvider method?


Solution

  • Rather than using useClass with theAPP_GUARD provider, you can add the AuthGuard to the providers array directly, and then use useExisting: AuthGuard for the APP_GUARD provider. Then, in your tests you can properly use overrideProvider(AuthGuard).useClass(MockedAuthGuard) without any issue, leaving your modules clean, and your tests the only ones referencing the mocks.

    @Module({
      imports: [],
      providers: [
        AuthGuard,
        {
          provide: APP_GUARD,
          useExisting: AuthGuard,
        },
      ],
    })
    export class AuthModule {}