본문 바로가기

Study/JavaScript

Jest

configuration | official docs  

$ npm install --g jest
$ npm install --D @types/jest
$ npm install --D jest
$ jest --init

 

  1. 터미널에서 jest를 global 옵션으로 설치하면, npm 명령어 jest를 실행할 수 있다. 
  2. 타입스크립트 코드를 테스트하는 것이 아니더라도 @types/jest를 설치하면 코드에디터에서 자동완성, 메서드 설명 확인 등의 기능을 이용할 수 있다. 
  3. jest --init 명령어를 사용하면, jest 설정과 관련된 파일(jest.config.js)을 간편하게 작성할 수 있다. 
    • script에 test - jest 자동 연결
    • typescript 코드의 테스트 설정
    • clearMocks: true | 테스트 함수를 실행할 때 마다 mock data에 관련된 것(ex. toHaveBeenCalledTimes)들을 초기화 (나중에 mock 부분 공부하면 이해할 수 있는 설정 )

 

jest --init

 

  1. coverage reports | test 코드가 전체 코드를 얼만큼 cover하고 있는지 확인할 수 있다. 
  2. 코드에 변경 사항이 생길 때 마다 자동으로 test 코드 실행하기 
    1. package.json => "test": "jest --watch" vs. "jest --watchAll" 
    2. watchAll 옵션은 프로젝트 폴더 내의 파일 중 하나라도 변화가 생기면, 모든 test 코드를 실행한다. 
    3. 반면 watch 옵션은 git과 함께 사용되며, 이전 commit과 달라진 파일에 해당하는 test 코드만 실행한다. 

test vs. describe

 describe는 관련 있는 여러 test를 하나로 묶은 것이다. 

 

// test
test('3 adds 5 equals 8', () => {
  const calculator = new Calculator()
  calculator.add(3, 5)

  expect(calculator.value).toBe(8)
})

// describe 
describe('calculator', ()=>{
  it('add', () => { // it은 'calculator' 를 가리킨다. it 대신 test 함수를 사용해도 무방함.
    const calculator = new Calculator()
    calculator.add(3, 5)
    expect(calculator.value).toBe(8)
  })  
  it('subtracts', () => {
    const calculator = new Calculator()
    calculator.substract(8, 1)
    expect(calculator.value).toBe(7)
  }) 
  it('multiply', () => {})
  //...
})

setup & tear down

Often while writing tests you have some setup work that needs to happen before tests run, and you have some finishing work that needs to happen after tests run. Jest provides helper functions to handle this.

=> 테스트 코드를 작성하다보면, 테스트를 실행하기 전, 또는 테스트를 마친 뒤에 해야할 일이 있을 수 있다. Jest의 헬퍼 함수를 이용하면 이러한 일들을 (코드의 반복 없이) 다룰 수 있다. 

 

앞서 살펴본 예제 코드에서 클래스의 인스턴스를 생성하는 코드가 setup work에 해당한다. 만약 매 테스트마다 calculator.value를 0으로 초기화해주는 작업이 필요하다면, 이 코드는 finishing work에 해당한다. 

 

beforeEach(() => {
  initializeCityDatabase();
});

afterEach(() => {
  clearCityDatabase();
});

test('city database has Vienna', () => {
  expect(isCity('Vienna')).toBeTruthy();
});

test('city database has San Juan', () => {
  expect(isCity('San Juan')).toBeTruthy();
});

 

describe('calculator', () => {
  let calculator
  beforeEach(() => {
    calculator = new Calculator()
  })
  
  // ... codes
}

error test

test('throws error', () => {
  expect(() => {
    // error 객체를 던지는 코드
  }).toThrow();
});

async test

  1. test의 콜백 함수가 Promise 객체를 return 하도록 작성
  2. test의 콜백 함수를 async 함수로 작성 
    • 비동기 함수가 실패하는 경우를 테스트할 때에는 try - catch 문을 이용한다. 

 

// async - await 이용 
describe('get product', () => {
  it('success with milk data', async () => {
    const result = await getProduct()
    expect(result).toEqual({ item: 'almond milk', price: 3 })
  })
  it('network error', async () => {
    try {
      await getProduct('error')
    } catch (error) {
      expect(error).toMatch(/error/)
    }
  })
})

mock

테스트 하고 싶은 기능이 다른 기능에 의존하고 있을 때, 다른 기능을 mock 으로 제공한다. 예를 들어 Cat 모듈의 비동기 함수 getAllBreeds를 이용하는 CatService 모듈을 테스트하고 싶다면, Cat을 mock으로 제공해야 한다. 

 

const CatService = require('../cat-service') // error occured when i hoisted this code to 1st line => https://jestjs.io/docs/mock-functions#mock-implementations
const Cat = require('../cat')
jest.mock('../cat')

const mockGetAllBreeds = () =>
  Promise.resolve({
    data: [{ breed: 'Abyssinian' }, { breed: 'Chartreux' }],
  })
Cat.mockImplementation(() => ({ getAllBreeds: mockGetAllBreeds }))

 

 

'Study > JavaScript' 카테고리의 다른 글

Testing, TDD  (0) 2022.09.05
shallow vs. deep copy  (0) 2022.08.08
Modern Syntax | Params, Spread, De-structuring  (0) 2022.05.26
Hoisting  (0) 2022.05.25
Var  (0) 2022.05.25