테스트 코드 (Jest.js)

한승준·2023년 12월 11일

TIL

목록 보기
35/41

https://mangkyu.tistory.com/143
단 통 시 인

단위 테스트(Unit Test)

  • 프로그램의 기본 단위인 모듈을 기준으로 독립적으로 하는 테스트

통합 테스트(Integration Test)

  • 모듈을 통합하는 과정에서 모듈 간의 호환성을 확인하기 위해 수행되는 테스트

단위 테스트(Unit Test)

https://github.com/Han9526/Node_Lv003-Architecture-
단위 테스트 직접해봄


import { prisma } from '../utils/prisma/index.js';

export class PostsRepository {
  findAllPosts = async () => {
    // ORM인 Prisma에서 Posts 모델의 findMany 메서드를 사용해 데이터를 요청합니다.
    const posts = await prisma.posts.findMany();

    return posts;
  };

  ...
}

위와 같은 코드는 PostsRepositoryfindMany() 함수를 직접적으로 의존하고 있습니다
테스트 시에 실제 데이터베이스에 접근하여 테스트해야 하는 문제가 있습니다.
이를 해결하기 위해 모킹(Mocking)을 사용합니다
실제 데이터베이스에 접근하는 대신 가상의 데이터를 mocking 함수로 생성하여 테스트할 수 있습니다. 또한 모킹(Mocking)을 사용하면 코드를 격리시켜 독립적으로 실행 가능한 테스트를 보장할 수 있어서 단위 테스트(Unit Test)를 수행 할 때 사용합니다

먼저 의존성 주입(Dependency Injection)을 해야합니다
의존성을 주입하는 방법은 많지만 생성자(constructor)를 이용해 의존성 주입 작업을 하겠습니다

export class PostsRepository {
  constructor(prisma) {
    // 생성자에서 전달받은 Prisma 클라이언트의 의존성을 주입합니다.
    this.prisma = prisma;
  }

  findAllPosts = async () => {
    // ORM인 Prisma에서 Posts 모델의 findMany 메서드를 사용해 데이터를 요청합니다.
    const posts = await this.prisma.posts.findMany();

    return posts;
  };
}

위와 같은 방법으로 아키텍쳐 3계층 controller,service,repository에 의존성 주입을 합니다

post.router.js

// 의존성주입
import { prisma } from '../utils/prisma/index.js';
import { PostsController } from '../controllers/posts.controller.js';
import { PostsService } from '../services/posts.service.js';
import { PostsRepository } from '../repositories/posts.repository.js';
import { UsersRepository } from '../repositories/users.repository.js';


// 의존성주입
const postsRepository = new PostsRepository(prisma);
const usersRepository = new UsersRepository(prisma);
const postsService = new PostsService(postsRepository, usersRepository);
const postsController = new PostsController(postsService);

이렇게 함으로써 각 계층에서 필요로 하는 데이터를 라우터에서 생성자를 통해 받아올 수 있게 되며, 이를 통해 의존성이 외부에서 주입되므로 각 계층은 외부 환경에 독립적으로 존재할 수 있습니다


위와 같은 방식으로 각 계층의 의존성을 주입했으니 이제 jest.js단위테스트를 진행

일단 findAllPosts만 테스트

// __tests__/unit/posts.repository.unit.spec.js

import { jest } from '@jest/globals';
import { PostsRepository } from '../../../src/repositories/posts.repository';

let mockPrisma = {
   Posts: {
      findMany: jest.fn(),
      findUnique: jest.fn(),
      create: jest.fn(),
      update: jest.fn(),
      delete: jest.fn(),
   },
   Users: {},
};
let postsRepository = new PostsRepository(mockPrisma);

describe('Posts Repository Unit Test', () => {
   // 각 test가 실행되기 전에 실행됩니다.
   beforeEach(() => {
      jest.resetAllMocks(); // 모든 Mock을 초기화합니다.
   });
   test('findAllPosts Method', async () => {
      // findMany Mock의 Return 값을 "findMany String"으로 설정합니다.
      const mockReturn = 'findMany String';
      mockPrisma.Posts.findMany.mockReturnValue(mockReturn);

      // postsRepository의 findAllPosts Method를 호출합니다.
      const posts = await postsRepository.findAllPosts();

      // prisma.posts의 findMany은 1번만 호출 되었습니다.
      expect(postsRepository.prisma.Posts.findMany).toHaveBeenCalledTimes(1);

      // mockPrisma의 Return과 출력된 findMany Method의 값이 일치하는지 비교합니다.
      expect(posts).toBe(mockReturn);
   });
});

터미널

 PASS  test/unit/repositories/posts.repositories.unit.spec.js
  Posts Repository Unit Test
    √ findAllPosts Method (4 ms)

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        0.669 s, estimated 1 s
Ran all test suites.
profile
한승준

0개의 댓글