Testing

Jest - Matcher란?

Creative_Lee 2022. 11. 12. 15:07

여러분들은 Jest로 테스트 코드를 작성할 때 다양한 Matcher를 사용하고 계시나요?

 

오늘은 Jest에서 테스트 코드를 작성할 때 자주 사용하는 Matcher에 대해서 알아보겠습니다.


1. toBe( value )

기본형을 비교할 때 자주 사용합니다. 값이 같은지 비교합니다.

대상이 원시형(primitive type)이라면 값을 비교하고,

참조형(reference type)이라면 같은 대상을 참조하는지 비교합니다. (얕은 비교)  

 

describe("toBe 테스트", () => {
  test("원시형 비교", () => {
    const result = "123";

    expect(result).toBe("123"); // test passed!
  });

  test("참조형 비교", () => {
    const result = [1, 2, 3];

    expect(result).toBe([1, 2, 3]); // test failed!
  });
});

때문에 위 테스트 코드에서 참조형인 배열 [1,2,3]의 toBe( ) 테스트는 실패하게 됩니다.


2. toEqual( value )

참조형을 비교할 때 자주 사용됩니다. 참조형의 모든 필드(프로퍼티, 요소)를 재귀적으로 돌며 비교해 줍니다. (깊은 비교)
원시형도 비교 가능합니다.

describe("toEqual 테스트", () => {
  test("원시형 비교", () => {
    const result = "123";

    expect(result).toEqual("123"); // test passed!
  });

  test("참조형 비교", () => {
    const result = [1, 2, 3];

    expect(result).toEqual([1, 2, 3]); // test passed!
  });
});

toBe( ) 테스트와 다르게 참조형인 배열의 toEqual() 테스트가 통과했습니다.


💢 주의할 점 

객체의 프로퍼티나, 배열의 요소에 undefined가 추가되어 있어도 테스트는 통과됩니다.

describe("toEqual undefined 테스트", () => {
  test("참조형 비교 - 객체", () => {
    const result = { a: 1, b: 2 };

    expect(result).toEqual({ a: 1, b: 2, c: undefined }); // test passed!!!!????
  });

  test("참조형 비교 - 배열", () => {
    const result = [1, 2, 3];

    expect(result).toEqual([1, 2, 3, undefined]); // test passed!!!!!???
  });
});

위 테스트 결과처럼 toEqual( ) 사용시 이 점에 유의하여 테스트 코드를 작성해야 합니다.


3. toStrictEqual( value )

위와 같은 toEqual( )의 문제를 toStrictEqual( )로 해결할 수 있습니다.

 toStrictEqual( )은 undefined까지 비교합니다.

describe("toStrictEqual undefined 테스트", () => {
  test("참조형 비교 - 객체", () => {
    const result = { a: 1, b: 2 };

    expect(result).toStrictEqual({ a: 1, b: 2, c: undefined }); // test failed ^^
  });

  test("참조형 비교 - 배열", () => {
    const result = [1, 2, 3];

    expect(result).toStrictEqual([1, 2, 3, undefined]); //  test failed ^^
  });
});

위 테스트는 실패합니다.

jest 공식 문서에서도 이러한 특징때문에 toStrictEqual( ) 이 선호된다고 알려주네요!


💢 꼼꼼한 toStrictEqual( )

 

toStrcitEqual( )은 객체의 인스턴스 타입까지 비교합니다.

describe.only("toEqual vs toStrictEqual 인스턴스 테스트", () => {
  class Test {
    constructor(test) {
      this.test = test;
    }
  }

  test("toEqual 인스턴스 테스트", () => {
    const instance = new Test(1);
    const normal = { test: 1 };

    expect(normal).toEqual(instance); // test passed !!
  });

  test("toStrictEqual 인스턴스 테스트", () => {
    const instance = new Test(1);
    const normal = { test: 1 };

    expect(normal).toStrictEqual(instance); // test failed !!
  });
});

같은 조건에 toEqual( ) 은 통과한 반면, toStrictEqual( )은 실패했습니다.


이 외에도 toStrictEqual( )은 [ ,1] 과 [undefined, 1] 을 다르다고 비교해 주는 등 보다 엄격하게 비교합니다. 

toStrictEqual( )의 특징을 잘 활용하여 테스트 코드를 작성해 봅시다.


4. toBeTruthy( ), toBeFalsy( )

JS는 boolean 값을 true, false 만으로 한정하지 않습니다. 
0, 빈 문자열 등을 false로 취급하는 것과 같이 말이죠.

이런값들을 비교할 때 toBeTrythy( ), toBeFalsy( )를 사용합니다.

describe("toBeTruthy / toBeFalsy 테스트", () => {
  test("toBeTruthy 테스트", () => {
    const result = "0";

    expect(result).toBeTruthy(); // test passed !!
  });

  test("toBeFalsy 테스트", () => {
    const result = 0;

    expect(result).toBeFalsy(); // test passed !!
  });
});

이 밖에도 Truthiness를 비교할 수 있는 matcher는 다양하니 알아두면 좋겠습니다.

  • toBeNull: 대상이 null 인지 검증합니다.
  • toBeUndefined: 대상이 undefined 인지 검증합니다.
  • toBeDefined: 대상이 정의되었는지 검증합니다.

5. toContain( element )

배열이 특정 요소를 가지고 있는지 검증합니다.

배열, 문자열, Set, 노드 리스트, HTML 콜렉션과 같은 iterable에 사용할 수 있습니다.

describe("toContain 테스트", () => {
  test("배열 테스트", () => {
    const result = [1, 2, 3];

    expect(result).toContain(1); // test passed !!
  });

  test("문자열 테스트", () => {
    const result = "문자열 테스트";

    expect(result).toContain("문자열"); // test passed !!
  });

  test("Set 테스트", () => {
    const result = new Set([1, 2, 3]);

    expect(result).toContain(1); // test passed !!
  });
});

6. toHaveLength( number )

대상이 length 프로퍼티를 가지고 있는지, 또한 length의 길이가 일치하는지 검증합니다.

배열이나 문자열의 길이를 체크할 때 유용합니다.

describe("toHaveLength 테스트", () => {
  test("배열 테스트", () => {
    const result = [1, 2, 3];

    expect(result).toHaveLength(3); // test passed !!
  });

  test("문자열 테스트", () => {
    const result = "문자열 테스트";

    expect(result).toHaveLength(7); // test passed !!
  });
});

7. toThrow( error? ) 

대상 함수를 호출했을 때 에러가 발생하는지 여부를 검증합니다.

describe("toThrow 테스트", () => {
  const testFunc = () => {
    throw new Error("에러 테스트 함수입니다.");
  };
  const errorObj = new Error("에러 테스트 함수입니다.");

  test("인자 X", () => {
    expect(testFunc).toThrow(); // test passed !!
  });

  test("문자열 인자", () => {
    expect(testFunc).toThrow("에러 테스트"); // test passed !!
  });

  test("Error 객체 인자", () => {
    expect(testFunc).toThrow(errorObj); // test passed !!
  });

  test("클래스 인자", () => {
    expect(testFunc).toThrow(Error); // test passed !!
  });
});

인자에 따른 기능차이

  • 인자가 없을 때:  에러 발생을 검증합니다.
  • 문자열 인자: 에러 발생 + 에러 메시지가 인자로 전달한 문자열을 포함하는지 검증합니다.
  • Error 객체 인자: 에러 발생 + 에러 메시지가 인자로 전달한 Error 객체의 메세지와 일치하는지 검증합니다.
  • class 인자: 에러 발생 + 에러 객체가 인자로 전달한 class의 instance 인지 검증합니다. 

8. toBeInstanceOf( Class )

대상 객체가 인자 클래스의 instance 인지 검증합니다.

describe("toBeInstanceOf 테스트", () => {
  class Test {}
  const output = new Test();
  const fake = {};

  test("인스턴스 O", () => {
    expect(output).toBeInstanceOf(Test); // test passed !!
  });
  test("인스턴스 X", () => {
    expect(fake).toBeInstanceOf(Test); // test failed !!
  });
});

여기까지 다양한 matcher를 알아보았습니다.
소개한 matcher 외의 더 많은 matcher에 대한 정보들은 공식 문서에서 찾으실 수 있습니다.

Jest Matcher 공식 문서

 

Expect · Jest

When you're writing tests, you often need to check that values meet certain conditions. expect gives you access to a number of "matchers" that let you validate different things.

jestjs.io

다음 포스트에서는 mock의 개념과 mock 메서드, mock 함수에 사용하는 Matcher에 대해 알아보겠습니다!

 

 

 

 

기본이 중요하다.

 

'Testing' 카테고리의 다른 글

Testing - 테스트 코드의 목적과 규칙, Jest 기본 문법  (0) 2022.11.03