Jest | 유용한 Matchers

Kate Jung·2022년 3월 16일
0

Front-end Test

목록 보기
2/17
post-thumbnail

📌 예시 실습 준비

📌 .toEqual(value)

객체 인스턴스의 모든 속성을 재귀적으로 비교 ("deep" equality 라고도 함)

  • .toBe 와 비슷하게 사용 가능

🔹 .toBe 와 차이점

◽ 숫자형일 경우

toEqual(), toBe() 모두 통과

  • 예시
    1. fn.test.js

      const fn = require("./fn");
      
      // toBe
      test("2 더하기 3은 5야.", () => {
        expect(fn.add(2, 3)).toBe(5);
      });
      
      // toEqual
      test("2 더하기 3은 5야.", () => {
        expect(fn.add(2, 3)).toEqual(5);
      });
    2. 테스트

      1. npm test
      2. 둘 다 통과

◽ 객체 or 배열일 경우

  1. .toStrictEqual(value) 2. .toEqual() 사용
  • toBe() 사용 불가 이유

    객체 or 배열은 재귀적으로 돌면서 값을 확인해야 하기 때문

  • toBe() 사용 시

    실패

    1. fn.js

      이름과 나이를 입력받아서 User 객체 리턴

      // 객체 제작 함수 추가
      const fn = {
        add: (num1, num2) => num1 + num2,
        makeUser: (name, age) => ({ name, age }), // 👈
      };
      
      module.exports = fn;
    2. 실패 케이스 제작(fn.test.js)

      const fn = require("./fn");
      
      test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
        expect(fn.makeUser("Mike", 30)).toBe({ // 👈 toBe 사용
          name: "Mike",
          age: 31, // 👈 다르게 적음
        });
      });
    3. test

      1. npm test

      2. 결과

        나이 부분이 다름

    4. 수정(fn.test.js)

      const fn = require("./fn");
      
      test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
        expect(fn.makeUser("Mike", 30)).toBe({
          name: "Mike",
          age: 30, // 👈 맞게 적음
        });
      });
    5. test

      1. npm test

      2. 결과

        실패

  • toEqual() 사용 시

    성공

    1. fn.test.js

      const fn = require("./fn");
      
      test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
        expect(fn.makeUser("Mike", 30)).toBe({ // 👈 toBe
          name: "Mike",
          age: 30,
        });
      });
      
      test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
        expect(fn.makeUser("Mike", 30)).toEqual({ // 👈 toEqual
          name: "Mike",
          age: 30,
        });
      });
    2. test

      1. npm test

      2. 결과

        • toBe() → 실패

        • toEqual() → 통과

        • 권고

          깊은 비교를 위해서 toBe()toStrictEqual()로 사용 추천

📌 .toStrictEqual(value)

보다 엄격하게 test 진행
( 객체가 동일한 types & 구조를 가지고 있는지 테스트 )

🔹 .toEqual 과 차이점

  • undefined 속성이 있는 key가 확인됨

    ex) {a: undefined, b: 2}{b: 2} 와 불일치

  • Array sparseness가 확인됨

    ex) [, 1] 는 [undefined, 1] 과 불일치

  • 객체 유형이 동일한지 확인됨

    ex) a 와 b 필드가 있는 클래스 인스턴스는 a 와 b 필드가 있는 리터럴 객체와 같지 않다.

🔹 .toEqual 과 비교 예시

1. 객체 속성이 같을 경우

모두 통과

  1. fn.test.js

    const fn = require("./fn");
    
    test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
      expect(fn.makeUser("Mike", 30)).toEqual({
        name: "Mike",
        age: 30,
      });
    });
    
    test("이름과 나이를 입력 받아서 객체를 반환해줘", () => {
      expect(fn.makeUser("Mike", 30)).toStrictEqual({
        name: "Mike",
        age: 30,
      });
    });
  2. 결과

    1. npm test

    2. 결과

      모두 통과

2. 객체 속성에 undefined 가 있을 경우

  • toEqual() → 불통
  • toStrictEqual() → 통과 (개발자의 의도와 일치)
  1. 객체 수정 (fn.js)

    const fn = {
      add: (num1, num2) => num1 + num2,
      makeUser: (name, age) => ({ name, age, gender: undefined }), 
    	// 👆 gender 추가
    };
    
    module.exports = fn;
  2. 결과

    1. npm test

    2. 결과

📌 .toBeNull()

null인지 확인

  • .toBe(null) 과 동일

    but, 오류 msg가 좀 더 친절함. → .toBeNull() 사용 추천

  • 예시

    const fn = require("./fn");
    
    test("null은 null이다.", () => {
      expect(null).toBeNull();
    });

📌 .toBeUndefined()

undefined 인지 확인

📌 .toBeDefined()

undefined 이 아닌지 확인

  • .not.toBe(undefined) 사용 가능

    but, 코드에서 직접 undefined를 참조하지 않는 것이 좋다.

📌 Boolean 관련

🔹 .toBeTruthy()

true인지 판별

  • JS의 6 falsy values (false0''nullundefinedNaN)외 모두 truthy

🔹 .toBeFalsy()

false 인지 판별

  • 예시 1 | 0
    // 통과
    const fn = require("./fn");
    
    test("0은 false 이다.", () => {
      expect(fn.add(1, -1)).toBeFalsy();
    });
  • 예시 2 | 문자열
    // [불통] false 값을 기대했는데 "helloworld"를 받아서 (빈 문자열이 아님)
    
    const fn = require("./fn");
    
    test("helloworld는 false 일까요?", () => {
      expect(fn.add("hello", "world")).toBeFalsy();
    });
    // [통과].toBeTruthy()로 수정
    
    test("비어있지 않은 문자열은 true입니다.", () => { // 👈 설명 수정
      expect(fn.add("hello", "world")).toBeTruthy(); // 👈
    });

📌 숫자 관련

🔹 초과/이상/미만/이하

.toBeGreaterThan(number | bigint) // 초과(크다)
.toBeGreaterThanOrEqual(number | bigint) // 이상(크거나 같다)
.toBeLessThan(number | bigint) // 미만(작다)
.toBeLessThanOrEqual(number | bigint) // 이하(작거나 같다)
  • 사용하는 경우 예시

    • 사용자가 입력한 id의 길이 제한

    • 업로드된 파일의 크기가 적당한지 판별

  • 예시

    1. fn.test.js

      const fn = require("./fn");
      
      test("ID는 10자 이하여야 합니다.", () => {
        const id = "THE_BLACK_ORDER";
        expect(id.length).toBeLessThanOrEqual(10);
      });
    2. 결과

      10보다 작거나 같아야 하는데 15자이기 때문에 실패함을 알려줌

    3. 수정 후, 통과

      const fn = require("./fn");
      
      test("ID는 10자 이하여야 합니다.", () => {
        const id = "THE_BLACK"; // 👈
        expect(id.length).toBeLessThanOrEqual(10);
      });

🔹 동일

.toBe
.toEqual
  • 예시
    // 정확하게 비밀 번호 4자리를 받을 때
    test("비밀번호 4자리", () => {
      const pw = "1234";
      expect(pw.length).toBe(4);
    });
    
    test("비밀번호 4자리", () => {
      const pw = "1234";
      expect(pw.length).toEqual(4);
    });

🔹 소수점

.toBeCloseTo(number, numDigits?) 로 근사치(가까운 값)인지 판별

  • 숫자 다룰 때 주의 사항

    몇몇 프로그램들(+ JS)은 소수점을 정확하게 계산 못함. → .toBeCloseTo 활용

  • 예시

    JS에서 0.1+0.2 ≠ 0.3 이다. → .toBeCloseTo 로 해결

    1. fn.test.js

      test("0.1 더하기 0.2 는 0.3 이다", () => {
        expect(fn.add(0.1, 0.2)).toBe(0.3); // 👈 toBe
      });
    2. 결과

      0.3이 아닌 0.30000000000000004 이 나옴

    3. 해결 (.toBeCloseTo)

      // 통과
      const fn = require("./fn");
      
      test("0.1 더하기 0.2 는 0.3 이다", () => {
        expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3); // 👈 toBeCloseTo
      });

📌 문자열 관련

🔹 .toMatch(regexp | string)

문자열이 정규식과 일치하는지 확인

  • 대소문자 구분 제거법

    .toMatch(/문자/i)

  • 예시

    1. a 있는지 확인

      // [실패] a 없기 때문
      test("Hello world에 a라는 글자가 있나요?", () => {
        expect("Hello world").toMatch(/a/);
      });
    2. H 있는지 확인

      // [성공] H 있기 때문
      test("Hello world에 a라는 글자가 있나요?", () => {
        expect("Hello world").toMatch(/H/);
      });
    3. 소문자(h) 있는지 확인

      // [실패] h 없기 때문
      test("Hello world에 a라는 글자가 있나요?", () => {
        expect("Hello world").toMatch(/h/);
      });
    4. 대소문자 구분 없애기

      // [성공] 대소문자 구분 없어져서 h 있음
      test("Hello world에 a라는 글자가 있나요?", () => {
        expect("Hello world").toMatch(/h/i);
      });

📌 배열 관련

🔹 .toContain(item)

배열에서 특정 item 이 있는지 확인

  • 예시
    1. 실패 케이스

      // [실패]
      test("userList에 Mike가 있나?", () => {
        const user = "Mike";
        const userList = ["Tom", "Jane", "Kai"]; // 👈 Mike 無
        expect(userList).toContain(user);
      });
    2. 수정

      // [성공]
      test("userList에 Mike가 있나?", () => {
        const user = "Mike";
        const userList = ["Tom", "Mike", "Kai"]; // 👈  Mike 有
        expect(userList).toContain(user);
      });

📌 .toThrow(error?)

🔹 별칭

.toThrowError(error?)

🔹 주의

코드를 함수로 래핑해야 함.

그렇지 않으면 오류가 잡히지 않고 assertion이 실패할 것.

🔹 인수 (optional)

  • 사용 이유

    특정 오류가 발생했는지 테스트하기 위해

  • 인수 유형

    • 정규 표현식

      error message matches the pattern

    • string

      error message includes the substring

    • error object

      error message is equal to the message property of the object

    • error class

      error object is instance of class

🔹 예시

  1. 예외 발생시키는 함수 제작 (fn.js)

    const fn = {
      add: (num1, num2) => num1 + num2,
      makeUser: (name, age) => ({ name, age, gender: undefined }),
      throwErr: () => { // 👈 이 함수 실행 시, 항상 예외 발생
        throw new Error('xx')
      }
    };
  2. 테스트 (fn.test.js)

    // [패스]
    const fn = require("./fn");
    
    test("이거 에러 나나요?", () => {
      expect(() => fn.throwErr()).toThrow();
    });
    /*
    패스 이유:
    - () => fn.throwErr()에서 에러가 발생 했고 toThrow를 썼기 때문에 패스 됨.
    - 이 테스트 케이스는 어떤 내용이든 상관없이 예외 발생 시, 무조건 패스. */
  3. 특정 에러 확인 테스트 (fn.test.js)

    특정 에러(ex. throw new Error('xx'))가 발생 되는지 테스트 하려면 toThrow 인수에 내용 전달하여 확인 가능

    // [실패] "oo"가 나와야 되는데 에러 msg는 "xx"
    test("이거 에러 나나요?", () => {
      expect(() => fn.throwErr()).toThrow("oo"); // 👈
    });
    // [통과] 에러 msg 가 "xx"로 동일하게 나옴 
    test("이거 에러 나나요?", () => {
      expect(() => fn.throwErr()).toThrow("xx"); // 👈
    });

참고

  • 코딩앙마_Jest 강좌
profile
복습 목적 블로그 입니다.

0개의 댓글