내일배움캠프 TIL (221229): jest 단위 테스트에 사용된 js new 연산자, class, constructor 분석

Jiumn·2022년 12월 29일
0

jest 단위 테스트에 사용된 new 연산자 분석

jest로 단위 테스트를 할 때 mock 객체를 만들기 위한 클래스를 생성하는데, 이때 new 연산자가 사용된다.

const PostRepository = require("../../repositories/posts.repository.js");

// posts.repository.js 에서는 아래 5개의 Method만을 사용합니다.
let mockPostsModel = {
  findAll: jest.fn(),
  findByPk: jest.fn(),
  create: jest.fn(),
  update: jest.fn(),
  destroy: jest.fn(),
};

let postRepository = new PostRepository(mockPostsModel);

객체의 인스턴트를 만드는 연산자라는 정도는 알고 있었지만 만들어지는 원리에 대해 궁금해서 찾아봤다.

new 연산자로 인스턴트를 만들기 위해서는 먼저 생성자 함수가 필요하다.

ㄴ> 2023.02.14 추가
후술하겠지만 여기서 생성된 PostRepository 클래스의 인스턴트는 생성자 함수가 아닌 class 문법으로 생성된 클래스였다.
이 포스팅을 쓸 당시에는 생성자 함수와 class 문법의 차이를 정확히 숙지하지 못하고 있었다. 혹시나 이 글을 보고 혼란을 가지셨을 분들께 심심한 사죄의 말씀을 드립니다.
(최근 자바스크립트의 생성자 함수 / prototype / class 문법의 차이를 정리하여 포스팅했으니 참고하실 분들은 이곳으로...)
https://velog.io/@jiumn/nbc-til-230210

그리고 충격적인 사실을 알게 되었는데...
생성자 함수를 선언할 때 빈 객체를 만들어 this에 할당한다고 한다...

// 생성자 함수 - 일반 함수와 구분하기 위해 관례상 대문자로 시작
function User(name) {
  // this = {};  (빈 객체가 암시적으로 만들어짐)

  // 새로운 프로퍼티를 this에 추가함
  this.name = name;
  this.isAdmin = false;

  // return this;  (this가 암시적으로 반환됨)
}

출처: https://ko.javascript.info/constructor-new

그동안 항상 나를 의문에 휩싸이게 만들었던 어디서 뚝 떨어졌는지 모르겠는 this라는 존재가 여기서 파생된 것이었다니...

모던 자바스크립트 튜토리얼에서 설명하는 내용을 도식화하면 다음과 같다.

출처: https://doitnow-man.tistory.com/132

this라는 빈 객체에 속성을 추가하는 것이므로 this.속성과 같은 형태로 할당이 되었던 것이었다.


js class와 constructor 정리

여기까지 이해했으면 맨 처음으로 살펴본 jest 단위 테스트 코드로 다시 돌아가보자.

let postRepository = new PostRepository(mockPostsModel);

이 코드에 쓰인 new 연산자를 통한 인스턴트가 생성되었다는 것은, 어딘가에 부모가 된 객체가 있다는 것이다.
(앞서 설명한 길게 생성자 함수가 아닌 class 문법으로 생성된 클래스다.)

vscode에서 ctrl 버튼과 함께 PostRespository를 클릭하면 해당 생성자 함수가 선언된 곳으로 이동하게 된다.

클릭과 함께 이동한 곳은 바로 repository 파일의 상단이다.

class PostRepository {
  constructor(postsModel) {
    this.postsModel = postsModel;
  }

  findAllPost = async () => {
    const posts = await this.postsModel.findAll();

    return posts;
  };
// 이하 생략

이곳에 PostRepository라는 클래스가 선언되어 있다.

이 클래스는 postsModel이라는 멤버변수(객체의 상태)를 가지고, findAllPost라는 메서드를 가지고 있다.

let postRepository = new PostRepository(mockPostsModel);

이제 이 코드가 달라보인다!

따라서 이 코드는 postsModel이 아닌 mockPostsModel이라는 멤버변수를 가지는 인스턴트를 생성한 것이다.

그리고 mockPostsModel은 다음과 같은 객체로 할당되어 있다.

let mockPostsModel = {
  findAll: jest.fn(),
  findByPk: jest.fn(),
  create: jest.fn(),
  update: jest.fn(),
  destroy: jest.fn(),
};

PostRepository라는 클래스가 가지고 있던 메서드 5가지를 jest.fn()라는 테스트용 가짜 함수의 속성을 가지도록 만든 것이다.

이것을 통해서 우리는 mocking 함수(=가짜 함수)를 가지고 직접적인 DB 조작 없이 테스트를 진행할 수 있다.

profile
Back-End Wep Developer. 꾸준함이 능력이다.

0개의 댓글