I have a simple controller that uses nest-keycloak-connect implementation of guard to restrict access to the resource. This is a snippet of the controller's code:
import { AuthGuard, ResourceGuard, Roles } from 'nest-keycloak-connect';
@UseGuards(AuthGuard, ResourceGuard)
@Controller('v1/info')
export class InfoController {
constructor(private readonly infoService: InfoService) {}
@Post('/storeinfo')
@Roles({ roles: ['USER'] })
@HttpCode(HttpStatus.OK)
async storeInfo(@Body() payload: InfoRequest): Promise<any> {
...
return response;
}
}
It works fine, but now I have to compose a unit-test for it. I got to a problem while trying to create the test module for it. I began with the
import { AuthGuard } from 'nest-keycloak-connect';
...
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [InfoController],
providers: [
InfoService,
{
provide: AuthGuard,
useValue: jest.fn().mockImplementation(() => true),
},
],
})
.overrideProvider(InfoService)
.useClass(InfoService)
.compile();
controller = module.get<InfoController>(InfoController);
claimsService = module.get<InfoService>(InfoService);
});
It failed with the error:
Nest can't resolve dependencies of the AuthGuard (?, KEYCLOAK_CONNECT_OPTIONS, KEYCLOAK_LOGGER, KeycloakMultiTenantService, Reflector). Please make sure that the argument KEYCLOAK_INSTANCE at index [0] is available in the RootTestModule context
I tried to add all required providers one by one for these dependencies up to this point:
import {
AuthGuard,
KEYCLOAK_INSTANCE,
KEYCLOAK_CONNECT_OPTIONS,
KEYCLOAK_LOGGER,
KeycloakMultiTenantService,
} from 'nest-keycloak-connect';
...
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [InfoController],
providers: [
InfoService,
{
provide: AuthGuard,
useValue: jest.fn().mockImplementation(() => true),
},
{
provide: KEYCLOAK_INSTANCE,
useValue: jest.fn().mockImplementation(() => true),
},
{
provide: KEYCLOAK_CONNECT_OPTIONS,
useValue: jest.fn().mockImplementation(() => true),
},
{
provide: KEYCLOAK_LOGGER,
useValue: jest.fn().mockImplementation(() => true),
},
{
provide: KeycloakMultiTenantService,
useValue: jest.fn().mockImplementation(() => true),
},
],
})
.overrideProvider(InfoService)
.useClass(InfoService)
.compile();
controller = module.get<InfoController>(InfoController);
claimsService = module.get<InfoService>(InfoService);
});
when it failed with the error
Nest can't resolve dependencies of the AuthGuard (KEYCLOAK_INSTANCE, KEYCLOAK_CONNECT_OPTIONS, KEYCLOAK_LOGGER, ?, Reflector). Please make sure that the argument KeycloakMultiTenantService at index [3] is available in the RootTestModule context
but 'nest-keycloak-connect' does not export the KeycloakMultiTenantService class:
error TS2724: '"nest-keycloak-connect"' has no exported member named 'KeycloakMultiTenantService'
so I'm totally stuck. I'm a newbie in typescript but I understand that I made a mess in the code above and it's quite possible I'm trying to do it in a wrong way. So question is: is it possible to mock nest-keycloak-connect's implementation of guard and test a nestJS guarded controller?