통합 테스트 코드 - (2) Jest

Jisoo Shin·2025년 9월 19일

테스트코드

목록 보기
2/2

코딩앙마의 Jest 강좌를 기반으로 작성되었습니다.
https://www.youtube.com/playlist?list=PLZKTXPmaJk8L1xCg_1cRjL5huINlP2JKt

📌 Matcher

: toBe 뒤에 나오는 함수를 Matcher라고 저장

  • yarn test를 하게 되면, test에 있는 모든 테스트 파일을 실행
  • 만약, 특정 파일만 실행하고 싶다면 뒤에 파일명을 붙이면 됨

(1) toBe : 숫자나 문자등 기본 타입값을 비교할때 사용

  • expect toBe : ~될것이라고 예상된다
  • expect not toBe : ~가 아닐것이라고 예상된다.

예시 코드는 다음과 같다.

test("1은 1이야", () => {
  expect(1).toBe(1);
});

test("2 더하기 3은 5야.", () => {
  expect(fn.add(2, 3).toBe(5);
});

test("3 더하기 3은 5가 아니야.", () => {
  expect(fn.add(3, 3).not.toBe(5);
});

(2) toEqual , toStrictEqual

  • 객체는 재귀적으로 돌면서 확인하기 때문에 toBe가 아니라 toEqual를 사용해야한다.
  • expect toBe : ~될것이라고 예상된다
  • expect not toBe : ~가 아닐것이라고 예상된다.

예시 코드는 다음과 같다.

// fn.js
// 객체를 만들어서 리턴해주는 함수 makeUser
const fn = {
  makeUser: (name, age) => ({name, age, gender: undefined}),
);
  
module.exports = fn;


// fn.test.js
test("이름과 나이를 전달받아서 객체를 반환해줘 (toEqual)를 사용", () => {
  expect(fn.makeUser("Mike", 30)).toEqual({
    name: "Mike",
    age: 30,
  });
});

test("이름과 나이를 전달받아서 객체를 반환해줘 (toStrictEqual)를 사용", () => {
  expect(fn.makeUser("Mike", 30)).toStrictEqual({
    name: "Mike",
    age: 30,
  });
});

  • 엄격하게는 gender: undefined도 있으니 gender도 있어야하는 것이 맞음
  • 따라서, 엄격하게 테스트를 원한다면 toStrictEqual를 사용해야함

(3) toBeNull,toBeUndefined,toBeDefined

  • toBeNull : null인 경우 통과
  • toBeUndefined : undefined인 경우 통과
  • toBeDefined : defined인 경우 통과

(4) toBeTruthy,toBeFalsy

  • boolean 값을 판별

(5) toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual,

  • 숫자를 비교하여 테스트하는 방법
    • ex. id 입력시 입력된 값의 길이 판별등에 도움이 됨
  • toBeGreaterThan : 크다
  • toBeGreaterThanOrEqual : 크거나 같다
  • toBeLessThan : 작다
  • toBeLessThanOrEqual : 작거나 같다

(6) toBeCloseTo

  • 근사치인지를 확인하는 방법
  • 소수점은 부동소수점이라서 0.3000000 이런식으로 노출됨
    • 따라서 근사치로 비교
test("0.1 더하기 0.2는 0.3입니다", () => {
  expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3);
});

(7) toMatch

  • 정규식을 사용해서 해당 정규식과 문자열이 일치하는지를 확인
test("Hello World 에 a라는 글자가 있는가?", () => {
  expect("Hello World").toMatch(/H/);
});

(8) toContain

  • 리스트에 해당 요소가 있는지 확인
test("유저 리스트에 Mike가 있는가", () => {
  const user = "Mike";
  const userList = ["Tom", "Mike"];
  expect(userList).toContain(user);
});

(9) toThrow

  • 함수 실행 시 예외가 발생한 경우
// fn.js에 throwErr 함수 추가
const fn = {
  throwErr : () => {
    throw new Error('xx');
  }
};


// fn.test.js
// 아무거나 에러가 발생했는지만을 확인
test("이거 에러가 나나요?", () => {
  expect(() => fn.throwErr().toThrow());
});


// 특정 에러가 발생한건지를 확인
test("이거 xx 에러가 나나요?", () => {
  expect(() => fn.throwErr().toThrow('xx'));
});

📌 비동기 코드 테스트하기

callBack 패턴

  • jest는 끝에 닿으면 바로 완료를 시켜버림
  • 따라서, 비동기 함수는 done을 사용해줘야함
    • done을 전달해주고, 이걸 호출해줘야함
  • 아래 예시에서는 3초간 기다렸다가 넘겨받은 callback 함수를 실행
  • 추가로 callback 패턴은 내부에서 try, catch 문을 통해 에러를 탐지할 수 있음
// fn.js
const fn = {
  getName : callback => {
    const name = "Mike";
    setTimeout(() => {
      callback(name);
    }, 3000);
  ),
};


// fn.test.js
// 아무거나 에러가 발생했는지만을 확인
test("3초 후에 받아온 이름은 Mike", done => {
  function callback(name) {
    expect((name).toBe('Mike');
    done();  // 이걸 만나야 비로소 종료
  }
  fn.getName(callback); // callback 함수를 넘겨줌
});

promise 사용 패턴

  • promise로 return 해주면, jest는 resolve 될때까지 기다려줌
    • 즉, done을 넘기지 않아도 괜찮!
    • 하지만 꼭 해당 함수를 return해줘야함!
  • Promise : 어떤 작업에 관한 "상태 정보"를 가지고 있는 객체
    • promise 객체를 보면 작업의 성고 유무, pending (진행중) 상태를 알 수 있음
    • 비동기 작업을 순차적으로 실행하기 위해서 사용
    • then, catch, finally의 3가지 메소드를 가짐
// fn.js
const fn = {
  getAge: () => {
    const age = 30;
    return new Promise((res, rej) => {
      setTimeout(() => {
        res(age);
      }, 3000);
    });
  },
};


// fn.test.js
// 아무거나 에러가 발생했는지만을 확인
test("3초 후에 받아온 이름은 Mike", () => {
  return  fn.getAge().then(age => {
    expect(age).toBe(30);
  });
});

// ❗️ 위 함수를 간단하게 하기 위해서 matcher 사용 가능
// 🔥 resolves, rejects 를 사용
test("3초 후에 받아온 이름은 Mike", () => {
  return expect(fn.getAge()).resolves.toBe(30);
});

async 와 await 사용하기

// getAge() 함수는 위와 동일


// fn.test.js
// 아무거나 에러가 발생했는지만을 확인
test("3초 후 나이 30", async () => {
  const age = await fn.getAge();
  expect(age).toBe(30);
});

📌 테스트 전후 작업

  • 테스트 전후로 수행해야하는 일을 쉽게 하기 위해 helper 함수를 제공

beforeEach : 각 test 직전에 실행됨

afterEach : 각 test 직후에 실행됨

아래 예시로 숫자를 초기화하는 로직을 추가해보면 다음과 같다.

// getAge() 함수는 위와 동일


// fn.test.js
// 아무거나 에러가 발생했는지만을 확인
test("3초 후 나이 30", async () => {
  const age = await fn.getAge();
  expect(age).toBe(30);
});

0개의 댓글