My Dream Being Visualized

Jest를 활용한 TDD 단위 테스트 - 3편 본문

Backend/TDD

Jest를 활용한 TDD 단위 테스트 - 3편

마틴킴 2021. 12. 1. 14:49
728x90

 개인 공부를 위한 공간입니다. 틀린 부분 지적해주시면 감사하겠습니다 (_ _)

 

지난 시간에, 간단한 예제를 만들어 보았다.

 

이번 시간엔, Using Matchers라는 주제로 넘어가보겠다.

https://jestjs.io/docs/using-matchers

 

 

Jest는 "matchers"를 쓰는데, 이는 다양한 방법으로 테스트 값을 도출해 내기 위함이다.

자주 사용되는 matchers를 소개해보겠다. 

https://jestjs.io/docs/expect (다른 리스트들도 볼 수 있다.)

 

 

Common Matchers

테스트 값을 도출하기에 가장 간단한 방법은, 값의 동일함을 테스트 하는 것이다.

test('two plus two is four', () => {
  expect(2 + 2).toBe(4);
});

해당 코드에서, "expect(2 + 2)"는 오브젝트이며, ".toBe(4)"가 matcher이다.

test('object assignment', () => {
  const data = {one: 1};
  data['two'] = 2;
  expect(data).toEqual({one: 1, two: 2});
});

하지만, Docs에서 값을 체크하고 싶을 때에는 toBe보다는 toEqual을 사용할 것을 권장한다.

(toEqual은 오브젝트 혹은 어레이의 값 하나 하나를 비교한다고 한다.)

test('adding positive numbers is not zero', () => {
  for (let a = 1; a < 10; a++) {
    for (let b = 1; b < 10; b++) {
      expect(a + b).not.toBe(0);
    }
  }
});

또한, 위와 같이 .not.toBe()를 활용하여 특정 값이 아니어야만 하는 상황도 테스트 할 수 있다. 

 

Truthiness

어떤 테스트에서는, undefined, null, false를 구분해야 할 때가 있지만 종종 다 같은 값으로 취급하고 싶을 수도 있다.

Jest는 하고 싶은 방향대로 모든 경우를 지원한다고 한다!

  • toBeNullnull만 확인
  • toBeUndefinedundefined만 확인
  • toBeDefinedtoBeUndefined의 반대
  • toBeTruthyif가 true로 반환하는 모든 경우
  • toBeFalsyif가 false로 반환하는 모든 경우
test('null', () => {
  const n = null;
  expect(n).toBeNull();				// null 이며
  expect(n).toBeDefined(); 			// 선언이 되었으며
  expect(n).not.toBeUndefined();		// undefined가 아니며
  expect(n).not.toBeTruthy();			// if가 true로 반환하지 않으며
  expect(n).toBeFalsy();			// if가 false로 반환한다.
});

test('zero', () => {
  const z = 0;
  expect(z).not.toBeNull();			// null이 아니며
  expect(z).toBeDefined();			// 선언이 되었으며
  expect(z).not.toBeUndefined();		// undefined가 아니며
  expect(z).not.toBeTruthy();			// if가 true로 반환하지 않으며
  expect(z).toBeFalsy();			// if가 false로 반환한다.
});

위와 같은 결과값을 볼 수 있다!

 

Numbers

대부분의 값을 비교하는 방법처럼 matcher 또한 동일하게 갖고 있다.

test('two plus two', () => {
  const value = 2 + 2;
  expect(value).toBeGreaterThan(3);
  expect(value).toBeGreaterThanOrEqual(3.5);
  expect(value).toBeLessThan(5);
  expect(value).toBeLessThanOrEqual(4.5);

  // toBe와 toEqual은 number에서는 동일하게 취급된다.
  expect(value).toBe(4);
  expect(value).toEqual(4);
});

부동소수점(floating point)은 toEqual보다는 toBeCloseTo를 권장한다.

(작은 반올림 할 수 있는 값 때문에 에러를 반환하고 싶지 않다면 말이다!)

test('adding floating point numbers', () => {
  const value = 0.1 + 0.2;
  //expect(value).toBe(0.3);           반올림 에러때문에 에러가 난다.
  expect(value).toBeCloseTo(0.3);
});

0.30000000...0004를 받았네..

 

Strings

toMatch를 사용하여, 정규표현식으로 확인할 수 있다.

test('there is no I in team', () => {
  expect('team').not.toMatch(/I/);
});

test('but there is a "stop" in Christoph', () => {
  expect('Christoph').toMatch(/stop/);
});

 

Arrays and iterables

어레이 혹은 반복되는 값이 특정 값을 가지고 있는지 toContain을 활용하여 체크할 수 있다.

const shoppingList = [
  'diapers',
  'kleenex',
  'trash bags',
  'paper towels',
  'milk',
];

test('the shopping list has milk on it', () => {
  expect(shoppingList).toContain('milk');
  expect(new Set(shoppingList)).toContain('milk');
});

 

Exceptions

함수가 실행되었을 때 에러를 던지는지 확인하고 싶다면, toThrow를 활용하면 된다!

(이후 NestJS 및 ExpressJS 서버에서 테스트코드 작성시 매우 많이 쓸 것으로 생각된다!!)

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

test('compiling android goes as expected', () => {
  // 에러를 던지는지 안 던지는지 여부
  expect(() => compileAndroidCode()).toThrow();
  // Error라는 이름으로 던지는 여부 (다른 에러 명으로 던지면 다르게 선언!)
  expect(() => compileAndroidCode()).toThrow(Error);

  // 에러 메세지와 동일한지 체크
  expect(() => compileAndroidCode()).toThrow('you are using the wrong JDK');
  // 에러메세지 내 'JDK'라는 문자열이 들어가있는지 체크
  expect(() => compileAndroidCode()).toThrow(/JDK/);
});
Note: the function that throws an exception needs to be invoked within a wrapping function otherwise the toThrow assertion will fail.
> expect내 wrapping function내 쓰지 않으면(() => {}) throw 하는 에러를 잡을 수 없다고 한다. 자바스크립트 문법과 관련된 것 같은데 정확한 이유를 모르겠다. 혹시 아시는 분 있으시면 댓글 좀...
> 들여다보지 않았다면, 또 toThrow() 기능을 사용할 때 버벅거릴 뻔 했다. 이래서 doc을 보라는 말이 있는 것 같다.

사용하는 방법에는 4가지가 있다.

  • 정규표현식: 에러메세지가 패턴과 일치
  • 문자열: 에러메세지가 서브스트링을 가짐
  • 에러 오브젝트: 에러메세지가 오브젝트의 메세지 프로펄티와 같음
  • 에러 클래스: 에러 오브젝트가 클래스의 인스턴스임

https://jestjs.io/docs/expect#tothrowerror

 

 

이상, Using Matchers와 관련된 내용이었다.
다음 시간엔 Testing Asynchronous Code와 관련된 내용이다!
어서 어서 정복하고 테스트 코드 짜는 습관을 기르고 싶다.