오늘은 배우워야 하는 내용이 너무 많았어서, 이론 베이스 정리는 생략해야겠다.
3 layerd architecture 구조
- controller : 클라이언트의 요청을 받아 서비스에 요청 처리를 전달한 후, 응답 값을 클라이언트에 전달
- service : 사용자의 요구사항(비즈니스 로직)을 처리 / db 정보가 필요할 때는 repository에 요청
- repository : DB관리 (연결, 해제, 자원 관리) / DB CRUD 작업
이렇게 분리한 아키텍처에 jest 라이브러리를 이용해 단위(unit) 테스트를 적용해 보았다.
아래 그림과 같은 Mocking framework를 이용해 가짜 객체인 mockData를 주입하여 DB에 접근하여 데이터를 수정하지 않고, 테스트를 진행할 수 있다.
- Mock 이란 테스트 코드에서 특정 코드를 실행하지 않고, 원하는 부분만을 테스트하고 싶을 때 실제로 존재하는 값처럼 사용할 수 있도록 만들어놓은 가짜 객체이다.
Repository 클래스는 Sequelize의 Posts 모델을 가지고 있는데, 단위테스트를 위해 의존성 주입(DI: Dependency Injection)을 통해, DB를 Mocking할 수 있다.
- 의존성 주입(DI: Dependency Injection)이란 하나의 객체가 다른 객체에게 의존성을 제공하는 방법을 말한다.
아래 코드에서는 의존성 주입을 구현하는 많은 방법 중 생성자 주입(Constructor Injection)을 활용하여 구현하였다.
- 생성자 주입(Constructor Injection)은 외부에서 의존성을 주입할 객체를 생성하기 위해 생성자(Constructor)를 호출할 때, 의존성을 전달하고, 객체는 전달받은 의존성을 이용해 코드를 실행하는 방식이다.
먼저, 의존성 주입을 하기 전 상태이다.
- PostService 클래스에서는, PostRepository 객체를 사용하여 DB의 데이터를 불러온다.
// services/posts.service.js
const PostRepository = require('../repositories/posts.repository');
class PostService {
findAllPost = async () => {
// 저장소(Repository)에게 데이터를 요청합니다.
const allPost = await this.postRepository.findAllPost();
...
};
...
}
// 의존성 주입 전 repositories/post.repository.js
const { Posts } = require('../models');
class PostRepository {
findAllPost = async () => {
const posts = await Posts.findAll();
return posts;
};
...
}
생성자 주입 방식을 사용하여 PostRepository에 의존성을 주입한다.
- 기존, posts.repository.js에서 require하던 DB 스키마 모델이 사라지고, 대신 PostRepository 클래스가 외부에서 객체화 될 때, constructor 함수를 통해 PostModel을 주입받도록 바뀌었다.
- PostService 클래스에서는 PostRepository 객체를 생성하며, Posts (DB 스키마)를 주입하고 있다.
- PostRepository Unit Test에서는 postRepository 객체를 생성하며, mockPostModel을 주입하고 있다.
// repositories/posts.repository.js
// PostRepository에 의존성 주입이 가능해짐
class PostRepository {
constructor(PostsModel) {
this.postsModel = PostsModel;
}
findAllPost = async () => {
const posts = await this.postsModel.findAll();
return posts;
};
...
}
// services/posts.service.js
// PostRepository에 Posts 모델을 주입
const PostRepository = require('../repositories/posts.repository');
const { Posts } = require("../models/index.js");
class PostService {
postRepository = new PostRepository(Posts);
...
}
// PostRepository Unit Test
const PostRepository = require("../../../repositories/posts.repository.js");
let mockPostsModel = {
findAll: jest.fn(),
}
let postRepository = new PostRepository(mockPostsModel); // mockPostsModel을 PostRepository에 주입
describe('Layered Architecture Pattern Posts Repository Unit Test', () => {
beforeEach(() => {
jest.resetAllMocks();
})
test('Posts Repository findAllPost Method', async () => {
// 테스트 코드 작성
});
});
이렇게, 조금 어려웠지만, 생성자 주입을 통한 의존성 주입에 대하여 잘 이해할 수 있게 되었다!
'항해99_10기 > 105일의 TIL & WIL' 카테고리의 다른 글
[5주차] [20221214] Object.assign() (0) | 2022.12.15 |
---|---|
[5주차] [20221213] TypeScript 핸드북 입문 (0) | 2022.12.13 |
[4주차 WIL] 2022.12.05 ~ 2022.12.10 회고 (0) | 2022.12.11 |
[TIL] [20221210] JavaScript, 프로토타입 기반(prototype-base) 객체지향(Object Oriented Programming) (0) | 2022.12.11 |
[TIL] [5주차] [20221209] object literal에서 spread operator (1) | 2022.12.09 |