포스트

jest 사용하기

안녕하세요 🐸

express.js 의 단위테스트 라이브러리인 jest 에 대해 정리하겠습니다.

Jest 란?

express.js 에서 가장 널리 사용되는 테스트 라이브러리.


테스트 파일 생성

기존의 파일명에 .test 혹은 .spec 을 연결하면 해당 파일의 테스트 파일로써 사용됩니다. 예시)

  • index.js 의 테스트 파일 index.test.js 혹은 index.spec.js

테스트 코드 구조

테스트 코드는 크게 3가지 구조로 이루어져 있습니다.

| 단계 | 역할 | 예제 | | ———————— | —————— | ——————————————— | | 1. 검증 대상 | 테스트 할 값을 jest 에 전달 | expect() | | 2. 중간 처리자(Modifiers) | 값의 상태를 변경 혹은 추가 | not() , resolves , rejects | | 3. 최종 검증 함수 (Matchers) | 값 비교 | toBe() , toEqual() , toBeCalledWith() 등 | 아래는 간단한 테스트 코드 예제 입니다.

1
2
3
4
5
6
7
8
test('1+1은 2입니다',()=>{
	expect(1+1).toBe(2);
})

test('1+1은 3이 아닙니다',()=>{
	expect(1+1).not.toBe(3);
})

최종 검증 함수(Matchers)는 값의 일치, 함수 호출 횟수, 특정 값과 함께 호출 됨을 검증할 수 있습니다.
사용할 수 있는 함수의 종류는 매우 많아서 아래 링크를 참고하여 사용하면 됩니다.
https://jestjs.io/docs/expect#matchers


테스트 코드 그룹화

같은 단위의 테스트는 그룹화 하여 테스트 할 수 있습니다.
모듈 내에서 if 를 통해 나뉘는 분기가 3개가 된다면 각각의 분기를 테스트 하나의 그룹으로 만들 수 있습니다.
describe() 를 사용하여 그룹화 합니다.
아래는 예시입니다.

1
2
3
4
5
6
7
8
9
describe('숫자 계산',()=>{
	test('더하기 검증',()=>{
		expect(5+5).toBe(10);
	})

	test('빼기 검증',()=>{
		expect(10-5).toBe(5);
	})
})

함수 모킹

테스트 코드에서 함수는 모킹하여 사용합니다.


목(Mock) 함수

일반 함수는 jest.fn() 을 통해 모킹 함수로 대체하여 사용할 수 있습니다.
아래는 사용 예시 입니다.

1
2
3
4
5
6
7
8
9
10
11
const mockFunc = jest.fn(); // 목 함수 생성
const mockFunc2 = jest.fn(()=>true) // 항상 true를 반환하는 목 함수

test('mockFunc',()=>{
	mockFunc()
	expect(mockFunc).toBeCalledTimes(1); // muckFunc 함수가 한번 실행 기대
});

test('mockFunc2',()=>{
	expect(mockFunc2()).toBe(true); // mockFunc2 의 응답이 true를 기대
})

Mock Return Value

목 함수의 응답 값을 명시하여 사용할 수 있습니다.
mockReturnValue() 를 기본적으로 사용하고 필요에 따라 mockReturnValueOnce() 등을 사용할 수도 있습니다.
아래는 사용 예시 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const mockFunc = jest.fn();
const mockFunc2 = jest.fn();

mockFunc.mockReturnValue('test');
mockFunc2.mockReturnValueOnce('a').mockReturnValueOnce('b').mockReturnValue('test'); // mockReturnValueOnce 는 한번 반환되고 끝

test('mockFunc',()=>{
	expect(mockFunc()).toBe('test');
});

test('mockFunc2',()=>{
	expect(mockFunc2()).toBe('a'); // mockReturnValueOnce 했던 첫 번째 응답
	expect(mockFunc2()).toBe('b'); // mockReturnValueOnce 했던 두 번째 응답
	expect(mockFunc2()).toBe('test');
	expect(mockFunc2()).toBe('test');
})

모듈 모킹

단위 테스트 코드는 DB에 접근하지 않는 것이 일반적입니다.
때문에 DB에 접근하는 모듈은 모킹하여 사용합니다.
jest.mock() 을 통해 모듈을 모킹합니다.
아래는 예시 코드 입니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
jest.mock('./services/test.js'); // test 서비스 모듈을 모킹 내부에서 exports 한 함수도 모킹됨
const {test1,test2} = require('./services/test.js'); // 모킹된 모듈의 함수

describe('test',()=>{
	test('test1', async()=>{
		test.mockReturnValue('ok'); // 모킹된 함수의 응답 값을 모킹
		const result = await test1(); // 모킹된 응답 'ok' 를 반환
		expect(result).toBe('ok');
	})

	test('test2',async()=>{
		test2.mockReturnValue('ok!'); // 모킹된 함수의 응답 값을 모킹
		const result = await test2(); // 모킹된 응답 'ok!' 를 반환
		expect(result).toBe('ok!');
	})
})

위 코드에서 test1 , test2 는 DB에 접근하는 함수로 가정하였을 때 이를 모킹하여 대체합니다.


테스트 커버리지

jest 라이브러리는 테스트 커버리지 확인을 지원합니다.
package.json 의 script 에 아래 내용을 추가합니다.

1
2
3
4
5
6
7
8
{
	//
	"script":{
		//
		"coverage":"jest --coverage"
	}
	//
}

이후 npm run coverage 를 입력하면 jest 라이브러리가 테스트 커버리지를 확인하여 콘솔에 보여줍니다.

아래는 제 환경에서 실행해본 결과입니다.

하지만 여기서 주의할 것은 테스트 커버리지에서 확인되는 비율은 개발자가 작성한 테스트 범위 내에서 얼마나 테스트가 되었는지를 보여준다는 점 입니다.
만약 사용자가 테스트 코드를 작성하지 않은 파일이 있다면 해당 파일의 커버리지는 확인할 수 없습니다.


참조 : https://jestjs.io/docs

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.