kimyu0218
  • [jest] jest 시작하기 (matcher/setup/teardown/mock)
    2024년 02월 03일 12시 59분 28초에 업로드 된 글입니다.
    작성자: @kimyu0218

    jest 란?

    jest는 단순함에 초점을 둔 자바스크립트 테스트 프레임워크다. 따라서 대부분의 자바스크립트 프로젝트에서 별도의 설정없이 동작할 수 있도록 설계되었다. jest는 병렬 실행 기능을 제공하는데, 이를 통해 여러 테스트 파일을 동시에 실행하여 테스트 수행 속도를 향상시킨다. 뿐만 아니라 이전에 실패한 테스트를 먼저 실행하여 개발자가 변경된 부분에 대한 결과를 빠르게 감지하고 수정할 수 있도록 돕는다.

    jest의 특징
    • 별도의 설정없이 동작하도록 설계되었다.
    • 여러 테스트 파일을 동시에 실행하여 성능을 향상시킨다.
    • 이전에 실패한 테스트를 먼저 실행하여 빠른 피드백을 제공한다.
    • 테스트 파일의 소요시간에 따라 실행 순서를 재조정한다.

     

    matcher

    matcher는 결과값을 예상된 결과와 비교하는 데 사용된다. jest는 실패한 matcher를 추적하고 에러 메시지를 출력한다.

    expect(기댓값).matcher(예상결과);

    자주 사용되는 matcher로는 `toBe`와 `toEqual`이 있다.

    • `toBe` : 값과 데이터 타입이 완전히 일치하는지 확인하는 matcher로, 주로 원시 데이터 타입을 검사하는 데 사용된다.
    • `toEqual` : 값의 내용이 동일한지 비교하는 matcher로, 객체의 경우 내부 속성이 일치하는지 확인한다.
    🚨 `toBe`는 참조까지 비교하기 때문에 내부 속성이 같더라도 참조가 다르면 테스트에 실패한다.
    🚨 `toStrictEqual`은 내부 값과 함께 객체의 속성 순서까지 검사한다.

    jest는 에러를 검사하기 위한 matcher도 제공한다. `toThrow`는 함수가 에러를 던지는지 확인하는 matcher로, 에러의 내용이나 타입을 매개변수로 받을 수도 있다.

     

    setup & teardown

    setup과 teardown은 테스트 환경을 설정하고 정리하는 데 사용되는 개념이다. 데이터베이스와 함께 테스트하는 상황을 가정해보자. 테스트를 진행하기 전에는 커넥션을 맺는 과정이 필요하고, 테스트가 완료된 후에는 커넥션을 끊어주는 과정이 필요하다.

     

    one-time

    one-time은 전체 테스트에 대한 세팅과 정리를 한 번만 수행하는 것을 의미한다. `beforeAll`은 테스트 슈트 내의 모든 테스트가 실행되기 전에 한 번만 호출되는 함수다. 반면, `afterAll`은 모든 테스트가 실행된 후 한 번만 호출되는 함수다.

     

    each

    each는 반복적으로 수행되는 테스트케이스를 위한 설정이나 정리 작업을 수행할 때 사용된다. `beforeEach`는 각각의 테스트 케이스가 실행되기 전에 호출되고, `afterEach`는 각각의 테스트 케이스가 실행된 후에 호출된다.

     

    mock

    목을 이용하면 특정 함수의 동작을 시뮬레이션 할 수 있기 때문에 의존성을 해결할 수 있다.

    목은 실제 함수의 구현을 지우고 함수 호출 및 호출 시 전달되는 파라미터만 캡처하는 도구다. 특정 함수가 호출되었을 때 어떤 값이 반환되어야 하는지, 몇 번 호출되어야 하는지 등을 정의할 수 있다.

     

    앞서 말했듯이 목은 함수의 호출을 기록한다. 모든 목에는 `mock`이라는 속성이 존재한다. `mock` 속성은 함수 호출, 반환값, 호출 횟수에 대한 정보를 저장한다.

    // mock.instances : 함수가 생성한 인스턴스 정보
    const mockFn = jest.fn();
    const a = new mockFn();
    console.log(mockFn.mock.instances); // [<a>]
    // mock.calls : 함수가 호출될 대 전달된 인자들의 배열
    const mockFn = jest.fn();
    mockFn(1, 'hello');
    console.log(mockFn.mock.calls); // [[1, 'hello']]
    // mock.results : 함수 호출 결과
    const mockFn = jest.fn((x, y) => x + y);
    mockFn(2, 3);
    console.log(mockFn.mock.results); // [{ type: 'return', value: 5 }]

     

    `mockReturnValue`를 이용하면 목 함수가 호출될 때 반환할 값을 지정할 수 있다. 데이터베이스에 접근하는 함수가 있는 경우, 실제 DB에 접근하지 않고도 특정 값을 반환하도록 만들어야 할 때 유용하게 사용된다.

    const mockFn = jest.fn();
    mockFn.mockReturnValueOnce(10).mockReturnValueOnce('hello').mockReturnValue(true);
    
    mockFn(); // 10
    mockFn(); // 'hello'
    mockFn(); // true
    mockFn(); // true

     

    axios 모듈은 API를 호출한다. 하지만 테스트에서 실제로 API를 호출하면 테스트에 소요되는 시간이 늘어나 시간이 낭비된다. 따라서 모듈을 모킹하여 가상의 응답을 반환하도록 설정함으로써 이러한 문제를 피할 수 있다. `jest.mock('axios')`

     

    `jest.fn`은 기본적으로 모든 호출에 대해 `undefined`를 반환한다. 하지만 때때로 특정한 동작을 수행하도록 목 함수를 설정해야 할 수도 있다. 이때 `mockImplementation` 메서드가 유용하게 사용된다.

    const mockFn = jest
      .fn()
      .mockImplementationOnce((x, y) => x + y)
      .mockImplementationOnce((x, y) => x - y);
    
    mockFn(2, 3); // 5
    mockFn(7, 5); // 2
    mockFn(); // undefined
    🚨 `jest.fn`만으로도 특정 동작을 수행하도록 만들 수 있다. `jest.fn((x, y) => x + y)`

    참고자료

    'backend > 테스트' 카테고리의 다른 글

    [테스트] jest와 supertest로 단위/유닛 테스트 하기  (0) 2024.02.03
    댓글