우테코 테스트 코드로 본 Jest mock function - 2

김영우·2022년 11월 12일
1
post-thumbnail

mockRandoms 함수

const mockRandoms = (numbers) => {
  MissionUtils.Random.pickUniqueNumbersInRange = jest.fn();
  numbers.reduce((acc, number) => {
    return acc.mockReturnValueOnce(number);
  }, MissionUtils.Random.pickUniqueNumbersInRange);
};

지난번 포스팅에 이어 이번엔 mockRandoms함수 분석이다. 위 함수 또한 우테코 프리코스의 테스트 코드로 주어진 코드이다. 지난번과 마찬가지로 하나하나 분석해보자.


MissionUtils.Random.pickUniqueNumbersInRange = jest.fn();

함수 내부 첫 번째 부분이다. 지난번과 달라진 부분은 대입 연산자의 좌측 부분밖에 없으니 이 부분만을 보겠다. 앞으로 중복되는 부분은 생략하고 진행할 예정이니 궁금한 내용이 있다면 지난번 포스팅을 참고하기 바란다.


class Random{
  
  static pickUniqueNumbersInRange(startInclusive, endInclusive, count) {
    Random.#validateIntsRange(startInclusive, endInclusive, count);

    const result = [];

    for (let i = startInclusive; i <= endInclusive; i++) {
      result.push(i);
    }

    return Random.shuffle(result).slice(0, count);
  }
  
  static shuffle(array) {
    Random.#validateEmptyArray(array);

    return array.sort(() => Math.random() - 0.5);
  }
}

위 코드는 MissionUtilsrandom.js 중 필요한 부분만 발췌한 코드이다. 여기서 #validateIntsRange#validateEmptyArray의 내용을 살펴보았더니 그냥 에러를 처리하기 위한 부분이니 신경쓰지 않아도 좋다. (혹시 궁금해할 수 있을 것 같아 마지막 부분에 첨부해두었다)

pickUniqueNumbersInRange를 보면

const result = [];

for (let i = startInclusive; i <= endInclusive; i++) {
  result.push(i);
}

result배열을 선언해 인자값으로 입력된 시작 숫자부터 끝 숫자를 모두 추가해주는 모습을 확인할 수 있다. 그 후

Random.shuffle(result).slice(0, count);

의 반환값을 반환해줌을 확인할 수 있다.

array.sort(() => Math.random() - 0.5);

shuffle 메서드를 보면 이러한 값을 리턴해줌을 확인할 수 있다.

mdn web docs를 확인해본 결과 sort 메서드는 정렬된 배열을 반환한다. 또, 정렬 순서를 정의하는 함수를 인자값으로 전달받는다.

() => Math.random() - 0.5

이 친구가 정렬 순서를 정의 하는 함수인 것이다. Math.random이 무엇인지 알아보자.

다시 한번 mdn web docs를 확인해본 결과 Math.random은 0부터 1미만의 값들 중 랜덤한 숫자를 반환하는 함수이다.


종합해보자면 pickUniqueNumbersInRange 함수는 다음과 같은 순서로 동작한다.

  1. result 배열을 선언한다.
  2. 인자값으로 입력된 시작 숫자, 끝 숫자 사이의 모든 숫자들로 result 배열을 채운다.
  3. Math.random을 이용해서 result 배열의 순서를 섞는다.
  4. slice를 사용해 result 배열의 0 ~ count의 인덱스를 가진 요소들을 배열의 형태로 반환한다.

남은 뒷 부분을 분석해보자.

numbers.reduce((acc, number) => {
  return acc.mockReturnValueOnce(number);
}, MissionUtils.Random.pickUniqueNumbersInRange);

지난 포스팅에 다루지 않았던 함수가 하나 눈에 띈다.

jest 공식 문서를 찾아본 결과 mockReturnValueOnce 함수는 mock function의 리턴 값을 사용자의 지정 값으로 대체해주는 역할을 해준다는 것을 알 수 있었다.

const mockRandoms = (numbers) => {
  MissionUtils.Random.pickUniqueNumbersInRange = jest.fn();
  numbers.reduce((acc, number) => {
    return acc.mockReturnValueOnce(number);
  }, MissionUtils.Random.pickUniqueNumbersInRange);
};

이제 각각 분석한 코드를 하나로 합쳐서 보자.

위 함수의 실행 순서는 다음과 같다.

  1. numbers를 인자값으로 넘겨받는다.
  2. MissionUtils.Random.pickUniqueNumbersInRange를 mock function으로 만든다.
  3. numbers의 각 요소로 pickUniqueNumbersInRange의 반환값을 대체한다.
  4. numbers의 크기만큼 3과정을 반복한다.

종합해보자면 mockRandoms함수는 인자값으로 넘겨받은 numbers 배열의 요소들로 pickUniqueNumbersInRange 함수의 리턴값을 대체하는 역할을 수행한다.


다음 포스팅에서는 테스트 코드로 주어진 getLogSpy를 분석해보겠다.

const getLogSpy = () => {
  const logSpy = jest.spyOn(MissionUtils.Console, "print");
  logSpy.mockClear();
  return logSpy;
};
profile
불편한 일들을 개발로 풀어내고 싶은 프론트엔드 개발자입니다!

0개의 댓글