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?
Rather than using
useClasswith theAPP_GUARDprovider, you can add theAuthGuardto theprovidersarray directly, and then useuseExisting: AuthGuardfor theAPP_GUARDprovider. Then, in your tests you can properly useoverrideProvider(AuthGuard).useClass(MockedAuthGuard)without any issue, leaving your modules clean, and your tests the only ones referencing the mocks.