I am new to nestjs and to jest as well. I am trying to override a guard, but it's not working. So my folder structure is: "src/app.module.ts", "src/modules/auth/guards/myfile-guard.ts", "src/modules/auth/auth.module.ts","src/modules/user/user.controller.ts" and "src/modules/user" contains all user related files. I am testing e2e test for user controller, which have a get route "/users", which requires user to login, and it is determined by a guard and then mentioned of this guard is done in "src/modules/auth/auth.module.ts" as below:
@Module({
imports: [],
controllers: [AuthController],
providers: [
{
provide: APP_GUARD,
useClass: IsAuthenticatedGuard,
},
AuthService,
],
exports: [AuthService],
})
export class AuthModule {}
my guard file: "src/modules/auth/guards/myfile-guard.ts" looks like:
@Injectable()
export class MyGuard extends AuthGuard('local')
implements CanActivate {
constructor(private readonly reflector: Reflector) {
super();
}
public canActivate(context: ExecutionContext): boolean {
const isPublic = this.reflector.get<boolean>(
'isPublic',
context.getHandler(),
);
if (isPublic) {
return true;
}
const request = context.switchToHttp().getRequest<Request>();
const isAuthenticated = request.isAuthenticated();
if (!isAuthenticated) {
throw new UnauthorizedException();
}
return true;
}
}
"src/app.module.ts" file, I have below code:
@Module({
imports: [
AuthModule,
UserModule,
],
controllers: [AppController],
providers: [],
})
export class AppModule {}
in "src/modules/user/user.controller.ts" file, I have below code:
@Controller('users')
export class UserController {
constructor(private readonly userService: UserService) {}
@Get()
async getUsers(): Promise<User[]> {
return this.userService.findUsers();
}
}
in "src/test/user-e2e-spec.ts" file, I have below code:
import { MyGuard } from '../src/modules/auth/guards/myfile-guard';
import { AppModule } from '../src/app.module';
describe('UserController (e2e)', () => {
let app: INestApplication;
const canActivate = jest.fn(() => true);
beforeEach(async () => {
const moduleFixture: TestingModule = await Test.createTestingModule({
imports: [AppModule],
providers: [],
})
.overrideGuard(MyGuard)
.useValue({ canActivate })
.compile();
app = moduleFixture.createNestApplication();
jest.resetAllMocks();
await app.init();
});
describe('@Get()', () => {
const requestUrl = '/users';
canActivate.mockReturnValueOnce(true);
it('returns list of users', async () => {
return request(app.getHttpServer())
.get(requestUrl)
.expect(200);
});
});
});
When I run the test, in place of 200, I always get 401 unauthorized, which means, "MyGuard" is not getting overridden by {canActivate}, I did even console.log in MyGuard class, it always goes there, where as it should not, I tried to search different questions related to same, few of them helped me to reach at this stage as well, below are few links which I already visited and which helped me: Nestjs unit-test - mock method guard Controller integration testing with nestJS using different guards
but still I cannot get it working as per the need, which is returning true from mocked or overridden canActivate. I am sure, either I am doing something wrong or I am missing something small. Please feel free to let me know if any further information is needed from my side I am thanking all in advance for your help