Hi I currently want to mock my configService injected as RegisterAs which allows me to have strong typing when accessing my environment variables, my problem with this is that when I mock the configService in my unit test and try to manipulate the environment values it doesn't I'm making it.
I show some of what I have.
My Nestjs Project:
src/
|- config/
| |- environment.ts
|- modules/
| |- auth/
| |- auth.service.ts
| |- auth.service.spec.ts
|- app.module.ts
|- main.ts
|+- ...
app.module.ts
import * as Joi from 'joi';
import { AuthModule } from './modules/auth/auth.module';
import { ConfigModule } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { ScheduleModule } from '@nestjs/schedule';
import env from './config/environment';
@Module({
imports: [
ScheduleModule.forRoot(),
ConfigModule.forRoot({ // <= I load the variables and validate them with Joi
isGlobal: true,
load: [env],
validationSchema: Joi.object().keys({
JWT_SESSION: Joi.string().trim(),
JWT_SESSION_EXP: Joi.number(),
}),
}),
AuthModule,
],
})
export class AppModule {}
config/environment.ts
import { registerAs } from '@nestjs/config';
export default registerAs('env', () => ({
jwtSession: process.env.JWT_SESSION || undefined,
expSession: Number(process.env.JWT_SESSION_EXP) || undefined,
}));
auth.service.ts
import * as moment from 'moment';
import { ConfigType } from '@nestjs/config';
import { Inject, Injectable, Logger } from '@nestjs/common';
import { AuthResponse } from './interfaces/login.interface';
import { AuthenticationDto } from './dto/auth.dto';
import { HttpService } from '@nestjs/axios';
import { JwtFidelity } from './interfaces/jwt-fidelity.interface';
import env from './../../config/environment';
import jwt_decode from 'jwt-decode';
import { lastValueFrom } from 'rxjs';
@Injectable()
export class AuthService {
constructor(
@Inject(env.KEY) private configService: ConfigType<typeof env>, // <= I inject the environment variables like this
) {}
isTokenExpired(): boolean { // <= This checks if the token has expired
if (!this.configService.jwtSession) return true;
if (!this.configService.expSession) return true;
return false;
}
}
auth.service.spec.ts Note: this is where i would like you to help me.
import { ConfigModule, ConfigService } from '@nestjs/config';
import { HttpModule, HttpService } from '@nestjs/axios';
import { Test, TestingModule } from '@nestjs/testing';
import { AuthService } from '../auth.service';
import environment from '../../../config/environment';
import { of } from 'rxjs';
const env = () => ({
auth: {
partner: {
jwtSeesion:
'jwt-token',
expSession: '1661878302',
},
},
});
describe('AuthService', () => {
let service: AuthService;
let httpService: HttpService;
let configService: ConfigService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [HttpModule, ConfigModule.forRoot({ load: [environment] })],
providers: [
HttpService,
AuthService,
ConfigService,
{ provide: 'CONFIGURATION(env)', useFactory: env },
],
})
.overrideProvider(HttpService)
.useValue({ request: jest.fn() })
.overrideProvider(ConfigService)
.useValue({ jwtSession: jest.fn() })
.compile();
service = module.get<AuthService>(AuthService);
httpService = module.get<HttpService>(HttpService);
configService = module.get<ConfigService>(ConfigService);
});
it('should be defined', () => {
expect(service).toBeDefined();
expect(httpService).toBeDefined();
expect(configService).toBeDefined();
});
describe('AuthController.isTokenExpired', () => {
it('variable jwtSession undefined', async () => {
configService.jwtSession = undefined; // <= I would like the possibility of doing something like that
jest.spyOn(configService, 'jwtSession').mockReturnValue('hola' as any); // <= Or something like that
const isExpired = await service.isTokenExpired();
expect(isExpired).toBeTruthy();
});
});
});
I would like that at the level of each test I can be able to manipulate the value of the environment variables that I have injected with @Inject(env.KEY) private configService: ConfigType<typeof env>, in my auth.service.ts