본문 바로가기

Project

[간단한 퀴즈 서비스] Day12~16 테스트 코드 추가, 검증 로직 추가

 소스코드가 길어지니 점점 코드 읽기가 불편해지고 복잡해진다.

 

 아직 레이어드 아키텍처가 적용되어 있지 않기에 리팩터링도 필요하다.

우선 동작되도록 만들고 조금씩 보안이나 성능, 유지보수 용이성을 기준으로 리팩터링을 할 예정이기에 여러 차례 이미 테스트했던 부분들을 다시 테스트해야 한다.

 

 더 이상 postman으로 했던 테스트를 또다시 하고 싶지 않아 졌다.

우선 매 번 클릭해서 하기가 번거롭고 시간이 꽤나 소요된다.

또한 사람이니까 테스트를 놓치는 부분도 생길 수 있기에

작성한 코드에 대한 신뢰성이 더 떨어진다.

 

 결국 테스트 코드를 추가할 수밖에 없다는 결론에 이르렀다.

jest를 이용해서 단위테스트부터 넣기로 하였다.

유저 파트 회원가입, 로그인, 비밀번호 변경 때 사용자가 입력한 값들이 정상적인지 확인하는 테스트를 넣었다.

  • describe
    • test
    • it
    • 관점의 차이
  • mock데이터 이용
  • req, res테스트
  • faker 테스트
  • 테스트에 대한 테스트
    • 메타 테스트
  • super test

express-validator의 검증 로직에서 withMessage()는 직전 검사 항목이 에러 나오면 나오게 될 문구이다. 만약 설정하지 않았다면 express-validator에 있는 기본 항목이 반영된다.

최소 영문 소문자 하나, 숫자 하나, 특수문자 하나

 이 두 개의. matches() 메서드는 정규 표현식을 사용하여 문자열의 유효성을 검사하는 것입니다. 각각의 정규 표현식은 다음과 같은 차이점을 가집니다:

  1. 첫 번째 정규 표현식:
javascript코드 복사
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[?!@#$%])[A-Za-z\\d?!@#$%]{8,20}$/

  • 설명: 이 정규 표현식은 다음 조건을 모두 충족해야 유효한 문자열로 간주합니다.
    • 최소 8자에서 최대 20자까지의 길이여야 합니다.
    • 적어도 하나의 소문자 ([a-z]), 하나의 대문자 ([A-Z]), 하나의 숫자 (\\d), 하나의 특수 문자 ([?!@#$%])를 포함해야 합니다.
    • 문자열은 [A-Za-z\\d?!@#$%] 이 문자들만으로 구성되어야 합니다.
  • 사용 예시: 이 정규 표현식은 비밀번호와 같은 강력한 보안 요구사항을 충족시키기 위해 사용됩니다. 대소문자, 숫자, 특수 문자가 모두 포함되어야 하며, 지정된 길이 범위 내에 있어야 합니다.
  1. 두 번째 정규 표현식:
javascript코드 복사
/^[A-Za-z\\d?!@#$%]{8,20}$/

  • 설명: 이 정규 표현식은 다음 조건을 만족해야 유효한 문자열로 간주합니다.
    • 최소 8자에서 최대 20자까지의 길이여야 합니다.
    • 문자열은 [A-Za-z\\d?!@#$%] 이 문자들만으로 구성되어야 합니다.
  • 사용 예시: 이 정규 표현식은 문자열의 구성 요소에 대한 강제 요구사항이 있지만, 특정 문자 클래스 (예: 소문자, 대문자, 숫자, 특수 문자)를 반드시 포함할 필요는 없을 때 사용될 수 있습니다. 예를 들어, 특정 API 또는 서비스에서는 특정 특수 문자를 허용하지 않는 경우가 있을 수 있습니다.

따라서 두 정규 표현식은 각각의 사용 사례와 요구사항에 맞게 선택되어야 합니다. 보안이 중요한 정보를 처리하는 경우 첫 번째 정규 표현식을 사용하여 강력한 비밀번호를 보장할 수 있으며, 다른 경우에는 두 번째 정규 표현식을 사용하여 간단한 문자열 유효성 검사를 수행할 수 있습니다.

퀴즈 결과 api

숫자 값 validation

  • JS의 경우 “10”도 숫자로 인지 됨
  • 문제는 validator에서 확인할 때는 강제 형 변환 되어서 숫자이지만
  • req.body를 처리할 때는 문자열 “10”인 상태이다
    • controller에서 강제 형 변환 할 수 있지만 미들웨어에서 변환 하 는 게 자연스럽다 생각했다
    • 그런데, validator middleware에서 형 변환까지 하는 게 맞는가?
const { body } = require("express-validator");

// 강제 형변환 미들웨어
const forceTypeConversion = (req, res, next) => {
  Object.keys(req.body).forEach((key) => {
    const value = req.body[key];
    const numberValue = parseFloat(value);
    if (!isNaN(numberValue) && Number.isInteger(numberValue)) {
      req.body[key] = numberValue;
    }
  });
  next();
};

// 숫자인지 확인하고, 정수인지 확인
const ensureInt = (value) => {
  if (!isNaN(value) && Number.isInteger(parseFloat(value))) {
    return true;
  }
  return false;
};

const quizValidators = {
  saveQuizResult: [
    forceTypeConversion,
    body("totalQuizCount")
      .exists()
      .withMessage("응시한 문제 수가 존재해야 합니다.")
      .notEmpty()
      .withMessage("응시한 문제 수가 비어 있을 수 없습니다.")
      .isInt({ min: 0 })
      .withMessage("응시한 문제 수가 0 이상의 정수여야 합니다.")
      .bail()
      .custom(ensureInt)
      .withMessage("응시한 문제 수는 문자열이 아닌 정수여야 합니다."),
    body("solvedQuizCount")
      .exists()
      .withMessage("맞춘 문제 수가 존재해야 합니다.")
      .notEmpty()
      .withMessage("맞춘 문제 수는 비어 있을 수 없습니다.")
      .custom(ensureInt)
      .withMessage("맞춘 문제 수는 문자열이 아닌 정수여야 합니다.")
      .isInt({ min: 0 })
      .withMessage("맞춘 문제 수는 0 이상의 정수여야 합니다."),
    body("totalQuizScore")
      .exists()
      .withMessage("맞춘 총 점수가 존재해야 합니다.")
      .notEmpty()
      .withMessage("맞춘 총 점수는 비어 있을 수 없습니다.")
      .custom(ensureInt)
      .withMessage("맞춘 총 점수는 문자열이 아닌 정수여야 합니다.")
      .isInt({ min: 0 })
      .withMessage("맞춘 총 점수는 0 이상의 정수여야 합니다."),
  ],
};

module.exports = quizValidators;

테스트 실패…

validatoin에만 유닛테스트 적용하였다.