How to mock configService as registerAs in my unit tests in nestjs

Viewed 29

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

0 Answers
Related