[TIL] Nest.js TDD 연습하기

ShinJuYong·2022년 8월 4일
0

공부한것들

목록 보기
33/33
post-thumbnail

TDD 연습

Ref : Node.js로 TDD하기

구현 목록 생각 및 함수생성하기.. -> 단위테스트 작성하기 -> 실제 코드작성하기

제목으로 이벤트들을 찾는 UseCase 만들기.

1.execute 함수가 정의됐는지 확인한다.

describe('FindEventByTitle', () => {
  const title = '제목';

  let result: FindEventByTitleUseCase;
  let eventRepository: IEventRepository;

  it('should have a execute defined', () => {
    expect(result.execute).toBeDefined();
  });
});

그러면 당연히 밑에 execute가 없다고 테스트를 실패내버린다.
![당연히 에러가 난다

이제 구현해서 테스트를 통과시키자

describe('FindEventByTitle', () => {
  let result: FindEventByTitleUseCase;

  const title = '제목';

  beforeEach(() => {
    result = new FindEventByTitleUseCase();
  });

  it('should have a execute defined', () => {
    expect(result.execute).toBeDefined();
  });
});
@Injectable()
export class FindEventByTitleUseCase
  implements
    IUseCase<FindEventByTitleUseCaseRequest, FindEventByTitleUseCaseResponse>
{
  async execute(
    request?: FindEventByTitleUseCaseRequest,
  ): Promise<FindEventByTitleUseCaseResponse> {
    throw new Error('Method not implemented.');
  }
}

자 이제 execute하기위해 Repository를 주입받아야한다.

describe('FindEventByTitle', () => {
  let result: FindEventByTitleUseCase;
  let eventRepository: MockProxy<IEventRepository>;

  const title = '제목';

  beforeEach(() => {
    eventRepository = mock<IEventRepository>();
    result = new FindEventByTitleUseCase(eventRepository);
  });

  it('should have a execute defined', () => {
    expect(result.execute).toBeDefined();
  });
});

이러면 생성자에서 인자를 받으라고 에러가 날것이다. 추가해주자

@Injectable()
export class FindEventByTitleUseCase
  implements
    IUseCase<FindEventByTitleUseCaseRequest, FindEventByTitleUseCaseResponse>
{
  constructor(
    @Inject(EVENT_REPOSITORY)
    private readonly eventRepository: IEventRepository,
  ) {}

  async execute(
    request?: FindEventByTitleUseCaseRequest,
  ): Promise<FindEventByTitleUseCaseResponse> {
    throw new Error('Method not implemented.');
  }
}

그러면 이제 검색을 하기위해선 Repository.findByTitle이 호출 돼야한다.

RED

GREEN

  it('should called a repository.findByTitle?', () => {
    const findEventByTitleUseCase = result.execute({ title: title });

    expect(eventRepository.findByTitle).toBeCalledTimes(1);
  });
  async execute(
    request?: FindEventByTitleUseCaseRequest,
  ): Promise<FindEventByTitleUseCaseResponse> {
    const { title } = request;

    const foundEvents = await this.eventRepository.findByTitle(title);

    return { code: '1', events: undefined };
  }

이제 위와 같이 천천히 Red-Green방식으로 구현한다

검색 결과가 없으면 NOTFOUND를 리턴시킨다.

RED

  it('should return NOTFOUND?', async () => {
    const findEventByTitleUseCaseNOTFOUND = await result.execute({
      title: title,
    });
    expect(eventRepository.findByTitle).toBeCalledTimes(1);
    expect(findEventByTitleUseCaseNOTFOUND).toEqual({
      code: 'NOTFOUND',
      events: undefined,
    });
  });

GREEN

  async execute(
    request?: FindEventByTitleUseCaseRequest,
  ): Promise<FindEventByTitleUseCaseResponse> {
    const { title } = request;

    const foundEvents = await this.eventRepository.findByTitle(title);

    if (!foundEvents) {
      return {
        code: 'NOTFOUND',
        events: undefined,
      };
    }

    return { code: '1', events: undefined };
  }

검색 결과가 존재하면 SUCCESS와 EVENTS를 보내준다

RED

  const foundEvent = [
    Event.create({
      eventExposure: EventExposure.create(true).value,
      eventTitle: EventTitle.create('t1').value,
      eventDescription: EventDescription.create('d1').value,
      eventStartDate: EventDate.create(new Date(2022, 8, 1)).value,
      eventEndDate: EventDate.create(new Date(2022, 8, 31)).value,
    }).value,
  ]; // 검색 결과를 임의로 만든다.
  
    beforeEach(() => {
    eventRepository = mock<IEventRepository>();
    result = new FindEventByTitleUseCase(eventRepository);
    eventRepository.findByTitle
      .calledWith('t1')
      .mockResolvedValueOnce(foundEvent);
  }); 
  // 't1'으로 검색을하면 해당 배열이 리턴될수 있게 만든다.

    it('SUCCESS', async () => {
    const findEventByTitleUseCaseSUCCESS = await result.execute({
      title: title,
    });
    expect(eventRepository.findByTitle).toBeCalledTimes(1);
    expect(findEventByTitleUseCaseSUCCESS).toEqual({
      code: 'SUCCESS',
      events: foundEvent,
    });
  });

GREEN

  async execute(
    request?: FindEventByTitleUseCaseRequest,
  ): Promise<FindEventByTitleUseCaseResponse> {
    const { title } = request;

    const foundEvents = await this.eventRepository.findByTitle(title);

    if (!foundEvents) {
      return {
        code: 'NOTFOUND',
        events: undefined,
      };
    }

    return { code: 'SUCCESS', events: foundEvents };
  }
  // 검색한 결과를 리턴할수있게 로직을 수정한다.

0개의 댓글