[NestJS] Jest 사용 방법

NestJS에서 Jest를 사용하는 방법에 대해 간략하게 알아보겠습니다.

Jest

Jest는 단순함에 초점을 맞춘 유쾌한 JavaScript 테스팅 프레임워크입니다.
Babel, TypeScript, Node, React, Angular, Vue 등을 사용하는 프로젝트에서 작동합니다.

시작하기

describe()

describe() 함수를 사용하면 작은 단위의 테스트 코드를 그룹화할 수 있습니다. 작성하는 테스트 코드가 특정 component 에 속하는 테스트 코드라면 다음과 같이 describe() 함수를 사용해서 해당 테스트 코드들을 그룹화하는 것이 좋습니다. 테스트 결과를 확인할 때 가시적으로 보기 편하게 테스트 케이스들을 확인할 수 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
describe('StudentService', () => {
test('getAll', () => {
...
});

test('getOne', () => {
...
});

test('create', () => {
...
});
});

it(), test()

테스트 케이스를 생성합니다. it() 함수 대신 test()도 사용 가능합니다.

1
2
3
it('should be 4', () => {
expect(2 + 2).toBe(4);
});
1
2
3
test('should be 4', () => {
expect(2 + 2).toBe(4);
});

expect()

값을 테스트할 때마다 expect() 함수가 사용됩니다. 테스트할 때 expect() 함수를 여러개 사용할 수 있습니다.

1
2
3
4
5
6
7
function bestJuiceFlavor() {
return 'apple';
}

test('the best flavor is apple', () => {
expect(bestJuiceFlavor()).toBe('apple');
});

Using Matchers

Common Matchers

toBe() 함수는 Object.is를 사용하여 정확한 동등성을 테스트합니다. 객체의 값을 확인하려면 대신 toEqual() 함수를 사용하세요.

1
2
3
it('two plus two is four', () => {
expect(2 + 2).toBe(4);
});
1
2
3
4
5
it('object assignment', () => {
const data = { one: 1 };
data['two'] = 2;
expect(data).toEqual({ one: 1, two: 2 });
});

Strings

toMatch() 함수를 사용하여 정규 표현식에 대해 문자열을 확인할 수 있습니다.

1
2
3
it('but there is a "ko" in hgko', () => {
expect('hgko').toMatch(/ko/);
});

Arrays and iterables

toContain() 함수를 사용하여 배열 또는 iterable에 특정 항목이 포함되어 있는지 확인할 수 있습니다.

1
2
3
4
5
6
7
8
9
const shoppingList = ['egg', 'coffee', 'tissue', 'milk'];

it('the shopping list has milk on it', () => {
// array
expect(shoppingList).toContain('milk');

// iterable
expect(new Set(shoppingList)).toContain('milk');
});

Exceptions

특정 함수가 호출될 때 오류가 발생하는지 테스트하려면 toThrow() 함수를 사용합니다.
예외를 발생시키는 함수는 래핑 함수 내에서 호출해야 합니다. 그렇지 않으면 toThrow assertion 이 실패합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
describe('getOne', () => {
it('shoule find a student', () => {
const student = service.getOne(1);
expect(student).toBeDefined();
});

it('should throw 404 error', () => {
try {
service.getOne(999);
} catch (e) {
expect(e).toBeInstanceOf(NotFoundException);
expect(e.message).toEqual(`Student with ID: 999 not found.`);
}
});
});

toBeInstanceOf(Class) 함수를 사용하여 객체가 클래스의 인스턴스인지 확인할 수 있습니다.

테스트 전/후 처리

beforeEach

각각의 테스트가 실행되기 전에 매번 함수를 실행합니다.
각각의 테스트 전에 각 테스트에서 사용할 전역 상태를 재설정하려는 경우에 유용합니다.
함수가 promise을 반환하거나 generator 인 경우 Jest는 테스트를 실행하기 전에 해당 promise가 해결될 때까지 기다립니다.
밀리초로 대기할 시간을 지정할 수 있습니다. (기본 시간 5초)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
let users: User[];

// test() 함수들이 실행될때마다 beforeEach()에서 설정한, users 데이터를 사용하게 된다.
beforeEach(async () => {
users.push({ id: 1, name: 'hgko' }, { id: 2, name: 'eden' });
});

test('find all users', () => {
// ... 테스트하면서 users의 데이터들을 가져와 사용한다.
});

test('create a user', () => {
// ... 테스트하면서 users의 데이터들을 가져와 사용한다.
});

afterEach

각각의 테스트가 완료된 후 함수를 실행합니다.

beforeAll

모든 테스트가 실행되기 전에 딱 한 번 함수를 실행합니다.

1
2
3
4
5
6
let connection;

beforeAll(() => {
// 테스트 실행하기전에 데이터베이스에 접속할 연결(Connection) 개체를 만든다.
conection = openConnection({ host: '...', port: '...' });
});

afterAll

모든 테스트가 완료된 후 함수를 실행합니다.

1
2
3
4
afterAll(() => {
// 데이터베이스 Connection을 종료한다.
conection.close();
});

실행

NestJS 개발환경에서 package.json 파일에 Testing 하는 명령어가 정의되어 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
// package.json
{
...
"scripts": {
...
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
}

다음과 같이 테스트 하려는 방식에 따라 명령어를 실행해서 테스트합니다.

1
2
3
4
5
6
7
# Unit 테스트
npm run test
npm run test:watch
npm run test:cov

# E2E 테스트
npm rum test:e2e

참고

Share