Jest Unit testing

00_8_3·2021년 1월 29일
0

Jest Unit testing

자동화된 테스트는 중요한 소프트웨어 개발의 필수적인 부분으로 여겨집니다. 자동화를 통해 테스트를 손쉽고 빠르게 반복 할 수 있습니다.

Jest란

Jest는 Facebook에서 만들었고 Twitter, Airbnb에서도 테스팅에 사용하고 있다. NestJS에서 내장되어있는 기능이다.

설치

$ npm i --save-dev @nestjs/testing

Unit testing

NestJS에서는 Module, Controller, Service를 생성하면 .spec.ts파일이 같이 생성된다. 해당 파일에서 Jset Unit testing을 하면 된다.

Jset Matchers

Jest는 보통 함수의 반환값을 인자로 받는 expect 함수를 제공한다. 이 함수는 받은 인자를 토대로 'expectation' 객체를 반환한다. 많은 테스트가 이 객체에 붙어 있는 'matchers'라고 불리는 메소드들을 호출함으로써 작성된다.

.toThrow의 경우 다음과 같이 감싸는 함수를 작성해야 테스트가 실패하지 않는다

function compileAndroidCode() {
  throw new Error('you are using the wrong JDK');
}

test('compiling android goes as expected', () => {
  expect(() => compileAndroidCode()).toThrow();
  expect(() => compileAndroidCode()).toThrow(Error);

  // 인자로 에러 메시지나 정규표현식을 넣을 수도 있다.
  expect(() => compileAndroidCode()).toThrow('you are using the wrong JDK');
  expect(() => compileAndroidCode()).toThrow(/JDK/);
});

.spec.ts 작성하기

movies.service.spec.ts

import { NotFoundException } from '@nestjs/common';
import { Test, TestingModule } from '@nestjs/testing';
import { MoviesService } from './movies.service';

describe('MoviesService', () => {
  let service: MoviesService;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [MoviesService],
    }).compile();

    service = module.get<MoviesService>(MoviesService);
  });

  describe('getAll', () => {
    //유닛테스트
    it('should return an array', () => {
      const result = service.getAll();
      expect(result).toBeInstanceOf(Array);
    });
  });
  describe('getOne', () => {
    //유닛테스트
    it('should return a movie', () => {
      service.create({
        title: 'test Movie',
        genres: ['test'],
        year: 2000,
      });
      const moive = service.getOne(1);
      expect(moive).toBeDefined();
      expect(moive.id).toEqual(1);
    });
    it('should thorw 404 error', () => {
      try {
        service.getOne(999);
      } catch (e) {
        expect(e).toBeInstanceOf(NotFoundException);
        expect(e.message).toEqual(`movie with id 999 not found`);
      }
    });
  });
  describe('deleteOne', () => {
    //유닛테스트
    it('delete a moive', () => {
      service.create({
        title: 'test movie',
        genres: ['test'],
        year: 2021,
      });
      const beforeDelete = service.getAll().length;
      service.deleteOne(1);
      const afterDelete = service.getAll().length;

      expect(afterDelete).toBeLessThan(beforeDelete);
      //   expect(afterDelte.length).toEqual(allMovies.length - 1);
    });
    it('shoudl return a 404', () => {
      try {
        service.deleteOne(999);
      } catch (e) {
        expect(e).toBeInstanceOf(NotFoundException);
      }
    });
  });

  describe('create', () => {
    it('should create a movie', () => {
      const beforeCreate = service.getAll().length;
      service.create({
        title: 'test moive',
        genres: ['testtest'],
        year: 2222,
      });
      const afterCreate = service.getAll().length;
      expect(afterCreate).toBeGreaterThan(beforeCreate);
    });
  });
  
  describe('update', () => {
    it('should update a movie', () => {
      service.create({
        title: 'test moive',
        genres: ['testtest'],
        year: 2222,
      });
      service.update(1, { title: 'updated Test' });
      const movie = service.getOne(1);
      expect(movie.title).toEqual('updated Test');
    });
    it('should throw a NotFoundException', () => {
      try {
        service.update(999, {});
      } catch (e) {
        expect(e).toBeInstanceOf(NotFoundException);
      }
    });
  });
});

test 실행

test:watch

NestJS에 내장되어 있어 스크립트를 따로 수정 하지 않아도 된다.
.spec.ts 파일을 모두 실행 해준다

$ npm run test:watch // or
$ npm run test

실행 시 Jest 테스트를 통과 했는지 못했는지 위와 같이 나온다.

test:cov

$ npm run test:cov

해당 명령으로 내 모듈에서 몇 퍼센트가 테스팅 작성 되었는지 알수 있다.

마침

Application Unit Test는 보다 탄력적이고 강력한 소프트웨어를 만들기 위한 첫 번째 단계입니다.
Code Base를 수정(추가)하는 동안 아무것도 깨뜨리지 않았음을 확신 할 수 있기 때문에 Unit Test를 사용하는 것은 리팩토링에 도움이 됩니다.

0개의 댓글