ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 4. NestJs & Hexagonal - [ 테스트 ] - 실패하는 테스트가 성공하도록 최소한으로 구현하기
    공부하기/node.js 2023. 2. 14. 18:46

    지난 포스팅글로 실패하는 survey module의 crud 및 search 메서드의 실패하는 테스트 케이스를 작성했습니다.

    이번 포스팅으로 실패하는 테스트가 성공할 수 있도록 최소한으로 구현해보도록 하겠습니다.

    포스팅으로 사용되는 코드는 Create 메서드를 기준으로 작성했습니다.

     

    코드는 여기를 참고해주세요

     

    survey module

    import { Module } from '@nestjs/common';
    import { TypeOrmModule } from '@nestjs/typeorm';
    import { CREATE_SURVEY_INBOUND_PORT } from './in-port/survey-create.ip';
    import { CREATE_SURVEY_OUTBOUND_PORT } from './out-port/survey-create.op';
    ...
    
    @Module({
      imports: [TypeOrmModule.forFeature([Survey])],
      controllers: [SurveyController],
      providers: [
        {
          provide: CREATE_SURVEY_INBOUND_PORT,
          useClass: SurveyCreateService,
        },
        {
          provide: CREATE_SURVEY_OUTBOUND_PORT,
          useClass: CreateSurveyRepository,
        },
        ...
      ],
    })
    export class SurveyModule {}
    • in bound port를 구현한 service와 token 값을 연결하여 DI되도록합니다.
    • out bound port를 구현한 adapter와 token값을 연결하여 DI되도록합니다.

    Create Survey Dto

    import { IsString } from 'class-validator';
    import { SurveyCreateInPortInputDto } from '../in-port/survey-create.ip';
    
    export class SurveyCreateDto implements SurveyCreateInPortInputDto {
      @IsString()
      name: string;
      @IsString()
      description: string;
    }

    -> in bound port의 input type을 implement한 Dto를 선언하고 controller의 body값을 체크할 수 있도록합니다.

     

    Create Survey Controller

    import {
      Body,
      Controller,
      Delete,
      Get,
      Inject,
      Param,
      ParseIntPipe,
      Patch,
      Post,
      Query,
    } from '@nestjs/common';
    import { SurveyCreateDto } from './dto/survey-create.dto';
    import {
      CreateSurveyInPort,
      CREATE_SURVEY_INBOUND_PORT,
    } from './in-port/survey-create.ip';
    ...
    
    @Controller('survey')
    export class SurveyController {
      constructor(
        ...
        @Inject(CREATE_SURVEY_INBOUND_PORT)
        private readonly createSurveyInPort: CreateSurveyInPort,
    
      ) {}
      
      ...
    
      @Post('create')
      create(@Body() surveyCreateDto: SurveyCreateDto) {
        return this.createSurveyInPort.execute(surveyCreateDto);
      }
      
      ...
      
    }

    -> 선언한 dto를 사용하여 http post 메서드의 body값을 검증합니다.

     

    SurveyCreateService

    import { Inject, Injectable } from '@nestjs/common';
    import {
      CreateSurveyInPort,
      SurveyCreateInPortInputDto,
      SurveyCreateInPortOutputDto,
    } from '../in-port/survey-create.ip';
    import {
      CreateSurveyOutPort,
      CREATE_SURVEY_OUTBOUND_PORT,
    } from '../out-port/survey-create.op';
    
    @Injectable()
    export class SurveyCreateService implements CreateSurveyInPort {
      constructor(
        @Inject(CREATE_SURVEY_OUTBOUND_PORT)
        private readonly createSurveyOutPort: CreateSurveyOutPort,
      ) {}
      execute(
        params: SurveyCreateInPortInputDto,
      ): Promise<SurveyCreateInPortOutputDto> {
        return this.createSurveyOutPort.execute(params);
      }
    }
    • in bound port를 구현합니다.
    • out bound port <interface>를 의존합니다.
    • token값을 활용하여 adapter가 DI될 수 있도록합니다.

    Survey Create Adapter

    import { InjectRepository } from '@nestjs/typeorm';
    import { Repository } from 'typeorm';
    import {
      CreateSurveyOutPort,
      SurveyCreateOutPortInputDto,
      SurveyCreateOutPortOutputDto,
    } from '../out-port/survey-create.op';
    import { Survey } from '../survey.entity';
    
    export class CreateSurveyRepository implements CreateSurveyOutPort {
      constructor(
        @InjectRepository(Survey) private readonly surveyRepo: Repository<Survey>,
      ) {}
    
      execute(
        params: SurveyCreateOutPortInputDto,
      ): Promise<SurveyCreateOutPortOutputDto> {
        return this.surveyRepo.save(params);
      }
    }
    • out bound port를 구현한 어댑터입니다.
    • survey create에 관련한 데이터 베이스 작업을 담당하는 어댑터입니다.

    Create Survey Test Case

    import {
      CreateSurveyOutPort,
      SurveyCreateOutPortInputDto,
      SurveyCreateOutPortOutputDto,
    } from 'src/survey/out-port/survey-create.op';
    import {
      SurveyCreateInPortInputDto,
      SurveyCreateInPortOutputDto,
    } from '../../in-port/survey-create.ip';
    import { SurveyCreateService } from '../survey-create.service';
    
    class MockCreateOutPort implements CreateSurveyOutPort {
      private readonly result: SurveyCreateOutPortOutputDto;
    
      constructor(params: SurveyCreateOutPortInputDto) {
        this.result = {
          id: 1,
          ...params,
        };
      }
    
      async execute(
        params: SurveyCreateOutPortInputDto,
      ): Promise<SurveyCreateOutPortOutputDto> {
        return this.result;
      }
    }
    
    describe('설문지를 생성한다.', () => {
      const survey: SurveyCreateInPortOutputDto = {
        id: 1,
        name: 'test-survey',
        description: 'test-desc',
      };
      const params: SurveyCreateInPortInputDto = {
        name: 'test-survey',
        description: 'test-desc',
      };
      const CreateSurveyService = new SurveyCreateService(
        new MockCreateOutPort(params),
      );
      
      test('설문지 생성.', async () => {
        const createResult = await CreateSurveyService.execute(params);
    
        expect(createResult).toStrictEqual(survey);
      });
    });

    결과

Designed by Tistory.