From 71ea6fc111db6650ee42f07b3e5ef8b00273e19a Mon Sep 17 00:00:00 2001 From: domingo1021 Date: Sun, 30 Jun 2024 15:01:09 +0800 Subject: [PATCH] refactor: refactor code to make code cleaner (#7) * refactor: move app port into env * refactor: refactor code to make code cleaner --- config/default.json | 1 + config/docker.json | 1 + config/test.json | 1 + src/cores/decorators/local.decorator.ts | 10 ++-- src/cores/decorators/user.decorator.ts | 10 ++-- src/cores/exceptions/general.exception.ts | 15 ++---- src/cores/guards/local.guard.ts | 1 + .../interceptors/requestId.interceptor.ts | 11 ++-- .../interceptors/responseLog.interceptor.ts | 12 ++--- src/cores/middlewares/requestId.middleware.ts | 1 + .../middlewares/requestLog.middleware.ts | 6 +-- src/main.ts | 6 ++- src/modules/app/app.module.ts | 7 +-- src/modules/auth/auth.module.ts | 2 +- src/modules/cache/cache.module.ts | 9 ++-- src/modules/hero/hero.controller.ts | 5 +- src/modules/hero/hero.repository.impl.ts | 19 ++----- src/modules/hero/hero.validator.ts | 2 +- src/modules/http/http.service.ts | 50 ++++++++----------- src/modules/logger/appLog.service.ts | 3 +- src/modules/logger/logger.module.ts | 5 +- src/modules/logger/systemLog.service.ts | 6 ++- test/modules/app/app.e2e.spec.ts | 1 + test/modules/hero/hero.e2e.spec.ts | 19 ++----- test/modules/http/http.service.spec.ts | 17 ++----- 25 files changed, 86 insertions(+), 134 deletions(-) diff --git a/config/default.json b/config/default.json index 22abcd3..a0c8053 100644 --- a/config/default.json +++ b/config/default.json @@ -1,4 +1,5 @@ { + "APP_PORT": 3000, "REDIS_HOST": "localhost", "REDIS_PORT": 6379 } \ No newline at end of file diff --git a/config/docker.json b/config/docker.json index 988b47d..1910278 100644 --- a/config/docker.json +++ b/config/docker.json @@ -1,4 +1,5 @@ { + "APP_PORT": 3000, "REDIS_HOST": "hero-cache", "REDIS_PORT": 6379 } \ No newline at end of file diff --git a/config/test.json b/config/test.json index 22abcd3..a0c8053 100644 --- a/config/test.json +++ b/config/test.json @@ -1,4 +1,5 @@ { + "APP_PORT": 3000, "REDIS_HOST": "localhost", "REDIS_PORT": 6379 } \ No newline at end of file diff --git a/src/cores/decorators/local.decorator.ts b/src/cores/decorators/local.decorator.ts index b653dfa..ef40227 100644 --- a/src/cores/decorators/local.decorator.ts +++ b/src/cores/decorators/local.decorator.ts @@ -7,9 +7,7 @@ import { InternalRequest } from '#cores/types'; * * Reference: https://github.com/nestjs/nest/issues/913#issuecomment-408822021 */ -export const Local = createParamDecorator( - (key: string, ctx: ExecutionContext) => { - const request = ctx.switchToHttp().getRequest(); - return key ? request.locals[key] : request.locals; - }, -); +export const Local = createParamDecorator((key: string, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + return key ? request.locals[key] : request.locals; +}); diff --git a/src/cores/decorators/user.decorator.ts b/src/cores/decorators/user.decorator.ts index 414b8f6..1631855 100644 --- a/src/cores/decorators/user.decorator.ts +++ b/src/cores/decorators/user.decorator.ts @@ -6,9 +6,7 @@ import { InternalRequest } from '#cores/types'; * @description Get the user authentication related object from the request object. * @param key - The key of the user object to retrieve. */ -export const User = createParamDecorator( - (key: string, ctx: ExecutionContext) => { - const request = ctx.switchToHttp().getRequest(); - return key ? request.user[key] : request.user; - }, -); +export const User = createParamDecorator((key: string, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + return key ? request.user[key] : request.user; +}); diff --git a/src/cores/exceptions/general.exception.ts b/src/cores/exceptions/general.exception.ts index 8fe8c7c..7708925 100644 --- a/src/cores/exceptions/general.exception.ts +++ b/src/cores/exceptions/general.exception.ts @@ -1,10 +1,5 @@ -import { - ExceptionFilter, - Catch, - ArgumentsHost, - HttpStatus, - HttpException, -} from '@nestjs/common'; +import { ExceptionFilter, Catch, ArgumentsHost, HttpStatus, HttpException } from '@nestjs/common'; + import { Response } from 'express'; import { InternalRequest, CustomErrorCodes, ErrorResponse } from '#cores/types'; @@ -42,9 +37,9 @@ export class AllExceptionsFilter implements ExceptionFilter { this.logger.info( requestId, - `Response, ${statusCode}, ${request.url}, ${JSON.stringify( - response.getHeaders(), - )}, Error: ${JSON.stringify(errorResponse)}`, + `Response, ${statusCode}, ${request.url}, ${JSON.stringify(response.getHeaders())}, Error: ${JSON.stringify( + errorResponse, + )}`, ); response.status(statusCode).json(errorResponse); diff --git a/src/cores/guards/local.guard.ts b/src/cores/guards/local.guard.ts index 4257723..396dff5 100644 --- a/src/cores/guards/local.guard.ts +++ b/src/cores/guards/local.guard.ts @@ -11,6 +11,7 @@ import { InternalRequest } from '#cores/types'; export class LocalAuthGuard implements CanActivate { private readonly USERNAME_KEY = 'Username'; private readonly PASSWORD_KEY = 'Password'; + constructor(private readonly authService: AuthService) {} async canActivate(context: ExecutionContext): Promise { diff --git a/src/cores/interceptors/requestId.interceptor.ts b/src/cores/interceptors/requestId.interceptor.ts index 86af3f5..67e9650 100644 --- a/src/cores/interceptors/requestId.interceptor.ts +++ b/src/cores/interceptors/requestId.interceptor.ts @@ -1,12 +1,9 @@ -import { - ExecutionContext, - CallHandler, - Injectable, - NestInterceptor, -} from '@nestjs/common'; +import { ExecutionContext, CallHandler, Injectable, NestInterceptor } from '@nestjs/common'; + import { Observable } from 'rxjs'; import { v4 as uuidv4 } from 'uuid'; -import { InternalRequest } from '../types'; + +import { InternalRequest } from '#cores/types'; /** * @description RequestIdInterceptor is a interceptor to help generate request id. diff --git a/src/cores/interceptors/responseLog.interceptor.ts b/src/cores/interceptors/responseLog.interceptor.ts index 8d14453..f444700 100644 --- a/src/cores/interceptors/responseLog.interceptor.ts +++ b/src/cores/interceptors/responseLog.interceptor.ts @@ -1,9 +1,5 @@ -import { - CallHandler, - ExecutionContext, - Injectable, - NestInterceptor, -} from '@nestjs/common'; +import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common'; + import { Observable } from 'rxjs'; import { tap } from 'rxjs/operators'; import { Response } from 'express'; @@ -38,9 +34,7 @@ export class ResponseLoggerInterceptor implements NestInterceptor { const { statusCode } = response; this.logger.log( requestId, - `Response, ${statusCode}, ${url}, ${JSON.stringify( - response.getHeaders(), - )}, ${JSON.stringify(data)}`, + `Response, ${statusCode}, ${url}, ${JSON.stringify(response.getHeaders())}, ${JSON.stringify(data)}`, ); }), ); diff --git a/src/cores/middlewares/requestId.middleware.ts b/src/cores/middlewares/requestId.middleware.ts index c8da273..d191a5b 100644 --- a/src/cores/middlewares/requestId.middleware.ts +++ b/src/cores/middlewares/requestId.middleware.ts @@ -1,4 +1,5 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; + import { v4 as uuidv4 } from 'uuid'; import { Request, Response, NextFunction } from 'express'; diff --git a/src/cores/middlewares/requestLog.middleware.ts b/src/cores/middlewares/requestLog.middleware.ts index f367b14..39de2ef 100644 --- a/src/cores/middlewares/requestLog.middleware.ts +++ b/src/cores/middlewares/requestLog.middleware.ts @@ -1,4 +1,5 @@ import { Injectable, NestMiddleware } from '@nestjs/common'; + import { Response, NextFunction } from 'express'; import { InternalRequest } from '#cores/types'; @@ -12,10 +13,7 @@ export class RequestLoggerMiddleware implements NestMiddleware { const requestId = req.locals.requestId; const { method, url, headers, body } = req; - this.logger.log( - requestId, - `Request, ${method}, ${url}, ${JSON.stringify(headers)}, ${JSON.stringify(body)}`, - ); + this.logger.log(requestId, `Request, ${method}, ${url}, ${JSON.stringify(headers)}, ${JSON.stringify(body)}`); next(); } diff --git a/src/main.ts b/src/main.ts index 34d9c2b..621f597 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,16 @@ import { NestFactory } from '@nestjs/core'; +import * as config from 'config'; + import { AppModule } from '#app/app.module'; import { SystemLog } from '#logger/systemLog.service'; async function bootstrap() { + const APP_PORT = +config.get('APP_PORT') || 3000; + const app = await NestFactory.create(AppModule, { logger: new SystemLog(), }); - await app.listen(3000); + await app.listen(APP_PORT); } bootstrap(); diff --git a/src/modules/app/app.module.ts b/src/modules/app/app.module.ts index 631693c..b8228ae 100644 --- a/src/modules/app/app.module.ts +++ b/src/modules/app/app.module.ts @@ -1,9 +1,4 @@ -import { - MiddlewareConsumer, - Module, - NestModule, - RequestMethod, -} from '@nestjs/common'; +import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'; import { APP_FILTER, APP_INTERCEPTOR } from '@nestjs/core'; import { ConfigModule } from '@nestjs/config'; diff --git a/src/modules/auth/auth.module.ts b/src/modules/auth/auth.module.ts index b466ae0..a980fec 100644 --- a/src/modules/auth/auth.module.ts +++ b/src/modules/auth/auth.module.ts @@ -2,7 +2,7 @@ import { Global, Module } from '@nestjs/common'; import { ExternalHttpModule } from '#http/http.module'; import { CacheConfigModule } from '#cache/cache.module'; -import { AuthService } from './auth.service'; +import { AuthService } from '#auth/auth.service'; @Global() @Module({ diff --git a/src/modules/cache/cache.module.ts b/src/modules/cache/cache.module.ts index 4de173d..df2fa13 100644 --- a/src/modules/cache/cache.module.ts +++ b/src/modules/cache/cache.module.ts @@ -4,7 +4,7 @@ import { CacheModule, CacheModuleAsyncOptions } from '@nestjs/cache-manager'; import { redisStore } from 'cache-manager-redis-store'; -import { CacheService } from './cache.service'; +import { CacheService } from '#cache/cache.service'; // Referece: https://github.com/dabroek/node-cache-manager-redis-store/issues/53 @Module({ @@ -20,11 +20,8 @@ import { CacheService } from './cache.service'; return { store: await redisStore({ socket: { - host: - configService.get('REDIS_HOST') || DEFAULT_REDIS_HOST, - port: +( - configService.get('REDIS_PORT') || DEFAULT_REDIS_PORT - ), + host: configService.get('REDIS_HOST') || DEFAULT_REDIS_HOST, + port: +(configService.get('REDIS_PORT') || DEFAULT_REDIS_PORT), }, }), ttl: 5000, diff --git a/src/modules/hero/hero.controller.ts b/src/modules/hero/hero.controller.ts index 5d00679..f752b44 100644 --- a/src/modules/hero/hero.controller.ts +++ b/src/modules/hero/hero.controller.ts @@ -27,10 +27,7 @@ export class HeroController { @UseGuards(LocalAuthGuard) @Get('heroes/:id') - async getHeroById( - @Param() params: GetSingleHeroReqParams, - @User() user: LocalUser, - ): Promise { + async getHeroById(@Param() params: GetSingleHeroReqParams, @User() user: LocalUser): Promise { const { id } = params; const { isAuthenticated } = user; return this.heroService.findById(id, isAuthenticated); diff --git a/src/modules/hero/hero.repository.impl.ts b/src/modules/hero/hero.repository.impl.ts index ca69bd0..a7a725f 100644 --- a/src/modules/hero/hero.repository.impl.ts +++ b/src/modules/hero/hero.repository.impl.ts @@ -10,6 +10,7 @@ export class HeroRepositoryImpl implements HeroRepository { private readonly GET_ALL_HEROES_WITH_PROFILE_KEY = 'heroes_with_profile'; private readonly GET_HERO_BY_ID_KEY = 'hero_'; // hero_{id} private readonly GET_HERO_WITH_PROFILE_BY_ID_KEY = 'hero_with_profile_'; // hero_with_profile_{id} + constructor( private readonly cacheService: CacheService, private readonly httpApi: ExternalHttpService, @@ -21,18 +22,13 @@ export class HeroRepositoryImpl implements HeroRepository { * @throws {InternalServerErrorException} */ async getAllHeroes(): Promise> { - const cachedHeroes = await this.cacheService.get( - this.GET_ALL_HEROES_KEY, - ); + const cachedHeroes = await this.cacheService.get(this.GET_ALL_HEROES_KEY); if (cachedHeroes) { return JSON.parse(cachedHeroes); } const heroes: Array = await this.httpApi.getHeroes(); - await this.cacheService.set( - this.GET_ALL_HEROES_KEY, - JSON.stringify(heroes), - ); + await this.cacheService.set(this.GET_ALL_HEROES_KEY, JSON.stringify(heroes)); return heroes; } @@ -44,9 +40,7 @@ export class HeroRepositoryImpl implements HeroRepository { * @throws {InternalServerErrorException} */ async getAllHeroesWithProfile(): Promise> { - const cachedHeroes = await this.cacheService.get( - this.GET_ALL_HEROES_WITH_PROFILE_KEY, - ); + const cachedHeroes = await this.cacheService.get(this.GET_ALL_HEROES_WITH_PROFILE_KEY); if (cachedHeroes) { return JSON.parse(cachedHeroes); } @@ -58,10 +52,7 @@ export class HeroRepositoryImpl implements HeroRepository { hero.profile = profile; }), ); - await this.cacheService.set( - this.GET_ALL_HEROES_WITH_PROFILE_KEY, - JSON.stringify(heroes), - ); + await this.cacheService.set(this.GET_ALL_HEROES_WITH_PROFILE_KEY, JSON.stringify(heroes)); return heroes; } diff --git a/src/modules/hero/hero.validator.ts b/src/modules/hero/hero.validator.ts index 98e4854..86bcb14 100644 --- a/src/modules/hero/hero.validator.ts +++ b/src/modules/hero/hero.validator.ts @@ -1,4 +1,4 @@ -import { Hero, HeroProfile } from './dto'; +import { Hero, HeroProfile } from '#hero/dto'; /** * A class that contains static utils methods to validate hero data. diff --git a/src/modules/http/http.service.ts b/src/modules/http/http.service.ts index 54899da..83344a9 100644 --- a/src/modules/http/http.service.ts +++ b/src/modules/http/http.service.ts @@ -1,5 +1,6 @@ import { Injectable, InternalServerErrorException } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; + import { AxiosError } from 'axios'; import { firstValueFrom, of } from 'rxjs'; import { catchError, map } from 'rxjs/operators'; @@ -32,10 +33,7 @@ export class ExternalHttpService { }), map((response) => response.data), map((heroes) => { - if ( - !Array.isArray(heroes) || - !heroes.every(HeroDataValidator.isHero) - ) { + if (!Array.isArray(heroes) || !heroes.every(HeroDataValidator.isHero)) { throw new InternalServerErrorException({ code: CustomErrorCodes.THIRDPARTY_API_RESPONSE_MISMATCH, message: `Invalid response format from upstream ${this.EXTERNAL_ENDPOINT.GET_HEROES}`, @@ -84,27 +82,25 @@ export class ExternalHttpService { */ async getHeroProfileById(id: string): Promise { return firstValueFrom( - this.httpService - .get(`${this.EXTERNAL_ENDPOINT.GET_HEROES}/${id}/profile`) - .pipe( - catchError((error: AxiosError) => { + this.httpService.get(`${this.EXTERNAL_ENDPOINT.GET_HEROES}/${id}/profile`).pipe( + catchError((error: AxiosError) => { + throw new InternalServerErrorException({ + code: CustomErrorCodes.THIRDPARTY_SERVER_ERROR, + message: error.message, + }); + }), + map((response) => response.data), + map((heroProfile) => { + if (!HeroDataValidator.isHeroProfile(heroProfile)) { throw new InternalServerErrorException({ - code: CustomErrorCodes.THIRDPARTY_SERVER_ERROR, - message: error.message, + code: CustomErrorCodes.THIRDPARTY_API_RESPONSE_MISMATCH, + message: `Invalid response format from upstream ${this.EXTERNAL_ENDPOINT.GET_HEROES}/${id}/profile`, }); - }), - map((response) => response.data), - map((heroProfile) => { - if (!HeroDataValidator.isHeroProfile(heroProfile)) { - throw new InternalServerErrorException({ - code: CustomErrorCodes.THIRDPARTY_API_RESPONSE_MISMATCH, - message: `Invalid response format from upstream ${this.EXTERNAL_ENDPOINT.GET_HEROES}/${id}/profile`, - }); - } + } - return heroProfile; - }), - ), + return heroProfile; + }), + ), ); } @@ -114,12 +110,10 @@ export class ExternalHttpService { */ async authenticate(username: string, password: string): Promise { return firstValueFrom( - this.httpService - .post(this.EXTERNAL_ENDPOINT.AUTHENTICATE, { name: username, password }) - .pipe( - map(() => true), - catchError(() => of(false)), - ), + this.httpService.post(this.EXTERNAL_ENDPOINT.AUTHENTICATE, { name: username, password }).pipe( + map(() => true), + catchError(() => of(false)), + ), ); } } diff --git a/src/modules/logger/appLog.service.ts b/src/modules/logger/appLog.service.ts index cfc8c46..9276c43 100644 --- a/src/modules/logger/appLog.service.ts +++ b/src/modules/logger/appLog.service.ts @@ -1,5 +1,6 @@ import { Global, Injectable } from '@nestjs/common'; -import { BaseLog } from './type/baseLog'; + +import { BaseLog } from '#logger/type/baseLog'; /** * @description Custom log implement Nest LoggerService, it will log all endpoint related logs. diff --git a/src/modules/logger/logger.module.ts b/src/modules/logger/logger.module.ts index 6bff88d..787e8f5 100644 --- a/src/modules/logger/logger.module.ts +++ b/src/modules/logger/logger.module.ts @@ -1,8 +1,9 @@ import { Module, Provider } from '@nestjs/common'; + import * as winston from 'winston'; -import { CustomLog } from './appLog.service'; -import { WinstonConfig } from './logger.config'; +import { CustomLog } from '#logger/appLog.service'; +import { WinstonConfig } from '#logger/logger.config'; const WinstonProvider: Provider = { provide: 'Winston', diff --git a/src/modules/logger/systemLog.service.ts b/src/modules/logger/systemLog.service.ts index 7fa5632..ad357aa 100644 --- a/src/modules/logger/systemLog.service.ts +++ b/src/modules/logger/systemLog.service.ts @@ -1,6 +1,8 @@ -import * as winston from 'winston'; import { LoggerService } from '@nestjs/common'; -import { BaseLog } from './type/baseLog'; + +import * as winston from 'winston'; + +import { BaseLog } from '#logger/type/baseLog'; /** * @description System log implement Nest LoggerService, it will log all server related system logs. diff --git a/test/modules/app/app.e2e.spec.ts b/test/modules/app/app.e2e.spec.ts index d9c63ca..227a411 100644 --- a/test/modules/app/app.e2e.spec.ts +++ b/test/modules/app/app.e2e.spec.ts @@ -1,5 +1,6 @@ import { Test, TestingModule } from '@nestjs/testing'; import { INestApplication } from '@nestjs/common'; + import * as request from 'supertest'; import { AppModule } from '#app/app.module'; diff --git a/test/modules/hero/hero.e2e.spec.ts b/test/modules/hero/hero.e2e.spec.ts index 1a75525..8392828 100644 --- a/test/modules/hero/hero.e2e.spec.ts +++ b/test/modules/hero/hero.e2e.spec.ts @@ -20,8 +20,7 @@ import { } from '#test/mocks'; describe('AppController (e2e)', () => { - const UUID_V4_REGEX = - /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/; + const UUID_V4_REGEX = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/; const baseUrl = 'https://hahow-recruit.herokuapp.com'; const authEndpoint = '/auth'; @@ -75,9 +74,7 @@ describe('AppController (e2e)', () => { .get('/heroes') .expect(500) .expect((res) => { - expect(res.body.code).toBe( - CustomErrorCodes.THIRDPARTY_SERVER_ERROR, - ); + expect(res.body.code).toBe(CustomErrorCodes.THIRDPARTY_SERVER_ERROR); expect(res.body.message).toBeDefined(); expect(res.body.requestId).toMatch(UUID_V4_REGEX); }); @@ -208,26 +205,20 @@ describe('AppController (e2e)', () => { .get('/heroes/1') .expect(500) .expect((res) => { - expect(res.body.code).toBe( - CustomErrorCodes.THIRDPARTY_SERVER_ERROR, - ); + expect(res.body.code).toBe(CustomErrorCodes.THIRDPARTY_SERVER_ERROR); expect(res.body.message).toBeDefined(); expect(res.body.requestId).toMatch(UUID_V4_REGEX); }); }); it('/heroes/:id, return 500 if response format is invalid.', () => { - nock(baseUrl) - .get(endpoint) - .reply(200, { code: 1000, message: 'Backend error' }); + nock(baseUrl).get(endpoint).reply(200, { code: 1000, message: 'Backend error' }); return request(server) .get('/heroes/1') .expect(500) .expect((res) => { - expect(res.body.code).toBe( - CustomErrorCodes.THIRDPARTY_API_RESPONSE_MISMATCH, - ); + expect(res.body.code).toBe(CustomErrorCodes.THIRDPARTY_API_RESPONSE_MISMATCH); expect(res.body.message).toBeDefined(); expect(res.body.requestId).toMatch(UUID_V4_REGEX); }); diff --git a/test/modules/http/http.service.spec.ts b/test/modules/http/http.service.spec.ts index b42e47a..a068b61 100644 --- a/test/modules/http/http.service.spec.ts +++ b/test/modules/http/http.service.spec.ts @@ -1,6 +1,7 @@ import { Test, TestingModule } from '@nestjs/testing'; import { InternalServerErrorException } from '@nestjs/common'; import { HttpService } from '@nestjs/axios'; + import { asyncScheduler, scheduled, throwError } from 'rxjs'; import { ExternalHttpService } from '#http/http.service'; @@ -40,9 +41,7 @@ describe('ExternalHttpService', () => { { id: '1', name: 'Hero A', image: 'http://hahow.com/image1.jpg' }, { id: '2', name: 'Hero B', image: 'http://hahow.com/image2.jpg' }, ]; - spyHttpServiceGet.mockReturnValueOnce( - scheduled([{ data: heroes }], asyncScheduler), - ); + spyHttpServiceGet.mockReturnValueOnce(scheduled([{ data: heroes }], asyncScheduler)); await expect(service.getHeroes()).resolves.toEqual(heroes); }); @@ -52,13 +51,9 @@ describe('ExternalHttpService', () => { { id: '1', name: 'Hero A' }, // Missing 'image' property { id: '2', name: 'Hero B', image: 'http://hahow.com/image1.jpg' }, ]; - spyHttpServiceGet.mockReturnValueOnce( - scheduled([{ data: invalidResponse }], asyncScheduler), - ); + spyHttpServiceGet.mockReturnValueOnce(scheduled([{ data: invalidResponse }], asyncScheduler)); - await expect(service.getHeroes()).rejects.toThrow( - InternalServerErrorException, - ); + await expect(service.getHeroes()).rejects.toThrow(InternalServerErrorException); }); it('should throw InternalServerErrorException if there is a server error', async () => { @@ -69,9 +64,7 @@ describe('ExternalHttpService', () => { ), ); - await expect(service.getHeroes()).rejects.toThrow( - InternalServerErrorException, - ); + await expect(service.getHeroes()).rejects.toThrow(InternalServerErrorException); }); }); });