How to override APP_GUARD in E2E tests

18 Views Asked by At

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?

1

There are 1 best solutions below

1
Jay McDoniel On BEST ANSWER

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 {}