TIL | Jest 용어 정리

코딩앙마 - Jest 강좌강의 내용을 정리해보려고 한다.

개요

규모가 큰 프로젝트의 경우, 하나하나 테스팅하고 있을 시간이 없다. 따라서 자동화된 테스팅 툴을 사용해 테스팅을 진행한다. 기본적으로 파일 이름 내에 test가 있거나 __tests__ 폴더를 테스팅 해주지만, 특정 파일만 테스팅 하고 싶을 경우 마지막에 파일 이름을 넣어준다.

## 특정 파일 확인
yarn test 파일이름

기본 형태

출처: 코딩앙마 - Jest 강좌 #1 소개, 설치 및 간단한 테스트 작성
출처: 코딩앙마 - Jest 강좌 #2 유용한 Matchers

test('코드 설명', () => {
  expect(검증할 값).toBe(기대되는 값)
})

Matcher

  • toBe: 원시타입 체크 시 사용
  • toEqual, toStrictEqual: 참조타입 체크 시 사용

null, undefined, boolean 판별

  • toBeNull
  • toBeUndefined
  • toBeDefined
  • toBeTruthy
  • toBeFalsy
test('null은 null이야', () => {
	expect(null).toBeNull()
})

크다. 작다. 크거나 같다. 작거나 같다

  • toBeGreaterThan : 크다
  • toBeGreaterThanOrEqual : 크거나 같다
  • toBeLessThan : 작다
  • toBeLessThanOrEqual : 작거나 같다

숫자 테스팅 시 주의사항

JS에서 0.1 + 0.2 !== 0.3 이다.
JS는 메모리에 숫자를 64비트 부동소수점 형식으로 저장하게 되는데, 메모리엔 2진수가 저장되기 때문에 10진수를 2진수로 변환하게 된다. 이 과정에서 무한소수로 변환이 되고 64비트가 넘어가는 부분을 잘라내게 된다. 따라서 결과값은 0.30000000000000004이다.
Jest에서 이를 해결하기 위해서는 근사치로 비교해주는 toBeCloseTo 함수를 사용하면 된다.

test('0.1 더하기 0.2는 0.3이야.', () => {
	expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3) // pass
})

정규표현식 사용하기

  • toMatch(정규표현식)
test('Hello World에는 w가 있어.', () => {
	expect('Hello World').toMatch(/w/i) // pass
})

배열에서 요소 찾기

  • toContain()
test('userList에 test가 있어?', () => {
	const userList = ['Tom', 'Jane', 'Kai']
	expect(userList).toContain('test') // failed
})

에러체크

  • toThrow(): 에러가 발생만 하면 pass
  • toThrow(에러 이름): 특정 에러인지 확인
test('에러 발생 확인', () => {
	expect(() => fn.getThrowError()).toThrow('error')
})

비동기 체크

출처: 코딩앙마 - Jest 강좌 #3 비동기 코드 테스트

콜백패턴

엔진이 코드 하단부에 도달하면 실행이 그대로 끝이 나서 비동기 코드가 실행되지 않는다.
이를 위해 test('설명', 콜백) 에서 콜백 함수 인자로 특정 키워드(e.g, done)를 넣고, 특정 키워드에 엔진이 도달했을 때 끝나도록 설정한다.

const fn3 = {
  getName: (callback) => { // callback을 인자로 받고 3초 후 콜백함수를 실행함
    const name = 'Kim'
    setTimeout(() => {
      callback(name)
    }, 3000)
  }
}

// fn.test.js
test('3초 후 Kim이라는 이름을 출력', (done) => {
  function callback(name) {
  	expect(name).toBe('Kim')
    done() // 비동기 함수가 실행되고 done까지 만났을 때 비로소 종료
  }
  fn.getName(callback)
})

프로미스

Jest는 프로미스가 resolve, reject될 때까지 기다려주기 때문에 종료를 위한 특정 키워드를 쓸 필요가 없다. 대신에 프로미스를 리턴하는 함수 앞에 return 을 시켜줘야 한다.

const fn3 = {
  getPuppy: () => {
    const puppy = 'pup'
    return new Promise((res, rej) => {
      setTimeout(() => {
        res(puppy) // 프로미스 return
      }, 2000)
    })
  }
}

fn.test.js
test('2초 후 puppy "pup"을 출력', () => {
  return fn3.getPuppy().then((puppy) => {
    expect(puppy).toBe('pup')
  })
})

프로미스 패턴을 쓸 수 있는 것은 좋지만, 여전히 콜백패턴이 남아있다. 그럴 땐 resolves 혹은 rejects 체이닝으로 then 역할을 해보자.

test('2초 후 puppy "pup"을 출력', () => {
  return expect(fn3.getPuppy()).resolves.toBe('pup')
})

asnyc, await

async, await도 프로미스를 사용하기 때문에 상단 getPuppy 메서드를 그대로 사용하겠다.

test('2초 후 puppy "pup"을 출력 with asnyc, await', async () => {
  const puppy = await fn3.getPuppy()
  expect(puppy).toBe('pup')
})

테스트 전 후 처리 관련 함수

출처: 코딩앙마 - Jest 강좌 #4 테스트 전후 작업

  • beforeEach : 각 테스트 함수가 실행되기 전 실행되는 함수
  • afterEach : 각 테스트 함수가 실행된 후 실행되는 함수
  • beforeAll: 모든 함수가 실행되기 전 한번만 실행되는 함수
  • afterAll: 모든 함수가 실행된 후 한번만 실행되는 함수

⭐️ describe 밖의 beforeEach가 안의 beforeEach 보다 항상 먼저 실행된다.

describe("User 관련 작업", () => { // 관련작업을 한 데 묶을 수 있다.
  let user = {}

  beforeAll(async () => {
    // 작업 전 user Db 가져오기
    user = await fn3.connectUserDb()
  })

  afterAll(async () => {
    return fn3.disonnectUserDb()
  })

  test('이름은 Kim', () => {
    expect(user.name).toBe('Kim')
  })
})
  • only, skip
  • test.only(설명, () => {}) : 특정 테스트만 확인
  • test.skip(설명, () => {}) : 특정 테스트만 스킵

Mock 함수

출처: 코딩앙마 - Jest 강좌 #5 목 함수(Mock Functions)

jest.fn().mock

const mockFunc = jest.fn() // mock 함수 만들기
mockFunc.mock.calls // 함수의 호출 횟수, 호출된 인자값 확인 가능, [[인자], [인자, 인자], [인자]]
mockFunc.mock.results // 리턴된 값 확인, [{ type: 'return', value: 어쩌구 }]
  • mockReturnValueOnce: mock 함수의 리턴 값 설정
  • mockReturnValue: mock 함수의 마지막 요소의 리턴값 설정
mockFunc.
  .mockReturnValueOnce(바꿀 값)
  .mockReturnValueOnce(바꿀 값)
  .mockReturnValue(바꿀 값)
  • mockResolvedValue: 비동기 함수 흉내내기

jest.mock(함수 출처)

호출될 때마다 실제로 db등에 영향을 미치는 함수가 있다고 가정하자. 테스트를 하기 위해 함수를 직접 호출하고 db에 접속해 다시 되돌리는 일은 번거로울 수밖에 없다. 그럴 때 jest.mock()을 활용한다.
jest.mock()은 불러온 함수를 mocking module로 만들어 함수를 실제로 호출되지 않는다.

const func = require('./fn')

jest.mock('./fn') // mock module로 만듦
func.createUser.mockReturnValue({ name: 'Kim' }) // 함수의 리턴값을 변경

test('user 생성', () => {
  const user = fn.createUser('Kim')
  expect(user.name).toBe('Kim')
})

mock 함수의 호출회수, 인수 체크

  • toBeCalled(): 한번 이상 호출됐는지 체크
  • toBeCalledTimes(횟수): 정확한 호출횟수 체크
  • toBeCalledWith(인수...): 인수 체크
  • lastCalledWith(인수...): 마지막으로 실행된 함수의 인수만 체크

기타 expect 관련 함수들은 jest 공홈에서 확인할 수 있다.

좋은 웹페이지 즐겨찾기