WIL 9주차

jathazp·2022년 3월 7일
0

1. 실전프로젝트 2주차

실전 프로젝트 2주차가 끝났다.
이번 주는 챌린지 및 인증 관련 API 들을 구현하고 동작을 테스트했다. 또, 구현하기로 했던 캐릭터 옷입히기에 대해 팀원들과 함께 구현 방법을 고민하고 구현하기 시작했다.

다음으로, API 작성 과정에서 공통되어 사용되던 연산들을 모듈로 분리하여 코드를 간결화 하고 생산성을 향상 시키는 작업도 진행했다.

API 개수가 늘어남에 따라 일일히 동작테스트를 하는데 시간이 걸려 테스트 코드를 작성하기로 했다.

어떤것을 사용해 테스트 코드를 작성할지에 대한 고민도 했는데, 테스트 코드 자체가 서비스의 성능에 영향을 미치는게 아니니 국내 레퍼런스가 많고 쉽게 익힐 수 있는 Jest를 사용하기로 했다.

Jest는 원래 페이스북에서 React 전용으로 만든 테스팅 프레임워크 인데 요즘은 백엔드의 테스팅 프레임워크도 Jest로 많이 교체가 되는 추세라고 한다. 이전의 Mocha 와 같은 테스팅 도구와 비교하면 별도의 라이브러리가 없고 사용법이 간단하다다.

그런데 최근 Jest 공부를 하며 느낀게 테스트 코드 자체를 처음 작성하디보니 생각보다는 쉽지않다 ㅎㅎ..
그래도 간단한 테스트 코드를 몇 개 작성해보며 적응하는 중이다.

2. 배운 내용

1. 중복되는 코드에 대한 모듈 분리

const moment = require('moment');
const Proofshot = require('../models/proofShot');

module.exports = {
    //status 계산

    calcStatus: (challenges) => {
        for (const i of challenges) {
            const start = i.startAt;
            const cur = new Date().toLocaleDateString();
            const end = new Date(cur);
            const dateDiff = Math.ceil((end.getTime() - start.getTime()) / (1000 * 3600 * 24));
            if (dateDiff < 0) {
                i.status = 1; //시작 전
            } else if (dateDiff > 30) {
                i.status = 2; //완료
            } else {
                i.status = 0; //진행중
            }
        }
    },
    //참여자 수 계산
    calcParticipants: (challenges) => {
        for (const i of challenges) {
            i.participants = i.participants.length;
        }
    },

    //총 인증횟수 계산 await
    calcProofCnt: async (challenges, user) => {
        for (const i of challenges) {
            let challengeId = i._id;
            let proofCount = await Proofshot.count({ challengeId, userId: user.userId });
            i.proofCount = proofCount;
        }
    },

    //경과 날짜, round 계산
    calcPastDaysAndRound: (challenges) => {
        let today = moment().format('YYYY-MM-DD'); //2022-03-05 00:00:00
        for (const i of challenges) {
            let pastDays =
                (moment(today) - moment(moment(i.startAt).format('YYYY-MM-DD'))) /
                (1000 * 60 * 60 * 24);
            i.pastDays = pastDays;
            i.round = Math.floor(pastDays / 3) + 1;
        }
    },

    //금일 업로드 체크 await
    calcIsUpload: async (challenges) => {
        let today = moment().format('YYYY-MM-DD'); //2022-03-05 00:00:00
        for (const i of challenges) {
            //금일 인증 여부
            if (
                await Proofshot.findOne({
                    challengeId: i._id,
                    createdAt: {
                        $gte: new Date(today).toISOString(),
                        $lt: new Date(moment(today).add(1, 'days')).toISOString(),
                    },
                })
            ) {
                i.isUpload = true;
            } else i.isUpload = false;
        }
    },
};

ref) https://velog.io/@shin6403/NodeJs-requireexportsmodule.exports-Part.2

2.lean

mongoose Document는 아래와 같은 추가 정보를 포함한다.

Change tracking
Casting and validation
Getters and setters
Virtuals
save()

이런 식의 추가 정보와 메서드들을 포함하고 있기 때문에 Query 결과 값을 가지고 수정한 후 save() 메서드를 통해서 수정 된 내용을 DB에 반영할 수 있다.

const findAndUpdateName = async (oldName, newName) => {
  const user = await User.findOne({ name: oldName });
	user.name = newName;
	const savedUser = await user.save();

  return savedUser;
};

Plain Old Javascript Object (POJO)

그런데 만약 다른 정보나 메서드를 사용하지 않는다면 굳이 Mongoose Document를 사용 할 필요가 없다. lean() 메서드를 이용하면 Mongoose Document대신 POJO를 받을 수 있다

+) toObejct() 메서드를 이용하는 경우 Query 결과를 Mongoose Document로 만들기 위한 과정을 거쳤다가 다시 POJO로 변환되는 반면, lean() 메서드를 이용할 경우 중간 과정 없이 바로 POJO를 반환하기에 더 효율적이다.

ref) https://velog.io/@modolee/mongodb-document-to-javascript-object

0개의 댓글