TIL

TIL 240716 - Nest.js에서 jest를 이용해 테스트코드 구현

lemonpie611 2024. 7. 16. 21:21

트렐로 프로젝트 진행중

기본 CRUD에 드래그앤드롭까지 완료하고, 이제 테스트코드를 해보기로 했다...

드래그앤드롭 관련 내용은 목욜쯤에 올릴 예정

 

1. testcode

1) 기본 문법

describe ('TestUnitName', () => {
	beforeEach(() => {
    
    })
	it('TestName', () => {
    	
    })
})
  • describe : 여러 테스트를 모아놓은 그룹 단위
  • it : 최상위 폴더 내의 작은 테스트 단위들
  • beforeEach : 테스트 이전에 실행되는 부분으로, 초기화 같은 작업을 실행

2) 예시

# calc.spec.ts

describe('연산', () => {
  it('비교', () => {
    const a = 1;
    const b = 1;

    expect(a == b).toBe(true);
  });

  it('덧셈', () => {
    const a = 1;
    const b = 1;

    expect(a + b).toBe(2);
  });
});

 

2. 테스트코드 matcher

  • toBe : 두 값을 정확히 비교, 기본형 데이터 타입에서는 문제없이 사용 가능하나 참조형에서는 다르게 나오기도 함
  • toEqual : 참조형 배열이나 객체를 비교할때도 사용 가능
  • toMatch : 정규식을 이용해 비교
  • toThrow : 특정 함수가 호출될 때 오류가 발생하는지 테스트

 

3. controller 테스트코드 기본 구현

다른걸 하기 전에, 가장 기본적으로 controller와 service가 정의되었는지부터 확인하는 테스트코드부터 만들었다.

import { Test, TestingModule } from '@nestjs/testing';
import { ListsController } from './lists.controller';
import { ListsService } from './lists.service';

// service 목킹
const mockListsService = {
  findAllList: jest.fn(),
  moveList: jest.fn(),
};

describe('ListsController', () => {
  let listsController: ListsController;
  let listsService: ListsService;

  beforeEach(async () => {
    // 데이터 초기화
    jest.clearAllMocks();
    jest.resetAllMocks();
    jest.restoreAllMocks();

    // controller, service 주입
    const module: TestingModule = await Test.createTestingModule({
      controllers: [ListsController],
      providers: [
        {
          provide: ListsService,
          useValue: mockListsService,
        },
      ],
    }).compile();

    listsController = module.get<ListsController>(ListsController);
    listsService = module.get<ListsService>(ListsService);
  });

  afterAll(async () => {
    jest.clearAllMocks();
    jest.resetAllMocks();
    jest.restoreAllMocks();
  });

  // controller, service 정의 여부 테스트
  it('should be defined', () => {
    expect(listsController).toBeDefined();
    expect(listsService).toBeDefined();
  });
});

 

1) service mocking

  • ListsController에서 참조할 listsService를 목킹해야 한다.
  • ListsService 클래스 내 함수들의 로직을 테스트에서는 간단히 퉁치도록 jest.fn()으로 설정한다.
  • 여기서 테스트를 실행할 함수는 findAllList, moveList 뿐이므로 두가지 함수만 jest.fn()로 정의해두었다.

 

2) listsController, listsService 정의

  • 모듈에 controller와 service를 주입했던것 처럼, 테스트코드에서도 testingModule에 주입시켜야 한다.
  • 여기서  controller은 controllers에 그대로 주입하면 되고, service의 경우 앞에서 만들었던 mockService로 대체하기 위해 useValue를 mockListsService로 설정한다. 
  • 모듈에 주입 후, module.get을 이용해 컴파일 한 것을 listsController, listsService에 저장한다.

3) jest 초기화

  • beforeEach 부분에는 module 주입 전에 임시로 저장되어있던 데이터들을 초기화시키는 과정을 거쳐야 한다. clearAllMocks, resetAllMocks, restoreAllMocks를 이용해 데이터를 초기화시킨다.

4) controller, service 정의 여부 테스트

  • it 단위에서 toBeDefind matcher를 이용하여 listsController와 listsService가 제대로 정이되었는지를 확인한다.