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.속성
과 같은 형태로 할당이 되었던 것이었다.
여기까지 이해했으면 맨 처음으로 살펴본 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 조작 없이 테스트를 진행할 수 있다.