Repository의 경우 연결되어 있는 하위 계층은 DB뿐!
Repository의 단위 테스트(UnitTest)를 구현하기 위해 DB에 접근하여 실제 데이터를 건드리지 않도록 DB를 Mocking하도록 하겠습니다.
__tests__
폴더 하위에unit
폴더를 생성하고,posts.repository.unit.spec.js
파일을 만들기- PostRepository 클래스의 단위 테스트 코드는 findAllPost, createPost 2개의 Method를 구현
- mockPostsModel이라는 실제 DB를 Mocking하기 위한 Mock 객체를 생성
=>jest.fn()
사용해서 Method Mocking- Mock Function을 이용해 PostRepository 클래스의 단위 테스트 코드를 구현
특정 Method가 몇번 호출되었는지, 어떤 값으로 호출되었는지 확인하고 싶거나 Mocking한 Method의 Return 값을 임의로 설정하고 싶을 때 해당하는 문법을 사용하여 설정할 수 있습니다.
// findAll Mock 함수를 실행했을 때, 결과값이 정상적으로 반영되었는지 확인합니다.
expect(findAllResultValue).toBe("Return Value");
// findAll Mock 함수가 몇번 호출했는지 확인합니다.
expect(findAll).toHaveBeenCalledTimes(1);
// __tests__/unit/posts.repository.unit.spec.js
const PostRepository = require("../../repositories/posts.repository");
//mocking을 할 떄 사용하는 객체
// 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);
//테스트 코드생성
describe("Layered Architecture Pattern Posts Repository Unit Test", () => {
// 각 test가 실행되기 전에 실행됩니다.
beforeEach(() => {
jest.resetAllMocks(); // 모든 Mock을 초기화합니다.
});
test("Posts Repository findAllPost Method", async () => {
mockPostsModel.findAll = jest.fn(() => {
return "findAll Result"; //findAllPost 메소드가 실행되면 return
});
const posts = await postRepository.findAllPost();
// postsModel에 있는 findAll Method는 한 번만 실행된다.
expect(mockPostsModel.findAll).toHaveBeenCalledTimes(1);
// postsModel에 있는 findAll Method의 결과값이 바로 return 되어야 한다.
expect(posts).toEqual("findAll Result");
});
test("Posts Repository createPost Method", async () => {
mockPostsModel.create = jest.fn(() => {
return "create Result";
});
const createPostParams = {
nickname: "createPostNickname",
password: "createPostPassword",
title: "createPostTitle",
content: "createPostContent",
};
const createPostData = await postRepository.createPost(
createPostParams.nickname,
createPostParams.password,
createPostParams.title,
createPostParams.content
);
//1. 할당이 제대로 됐는지 => postsModel.create Method의 결과가 createPostData와 일치
expect(createPostData).toEqual("create Result");
//2. 한 번 호출
expect(mockPostsModel.create).toHaveBeenCalledTimes(1);
//3. 어떤 방식으로 어떤 값이 호출되는지 검증=> {nickname, password, title, content}
expect(mockPostsModel.create).toHaveBeenCalledWith({
nickname: createPostParams.nickname,
password: createPostParams.password,
title: createPostParams.title,
content: createPostParams.content,
});
});
});
Repository Layer가 사용하는 DB를 Mocking하여 실제 DB에 접근하지 않도록 테스트 코드를 작성하였고, 성공 케이스의 단위 테스트를 구현할 수 있게 되었습니다! 😁