Jest로 ES6 클래스 메소드 조롱하기!

전제 조건



이 자습서를 시작하기 전에 작업 중인 JavaScript 프로젝트가 이미 있고 테스트에 관한 절대적인 기본 사항과 테스트를 작성하려는 이유를 이미 이해하고 있다고 가정합니다. 어렴풋이 낯익은 소리? 좋아요, 시작하겠습니다!

왜 우리는 조롱해야 합니까?



단위 테스트를 작성할 때 특정 시간에 테스트하는 특정 구성 요소(또는 단위)를 분리하는 것이 중요합니다. 이를 효과적으로 수행하지 않으면 테스트하려는 부분 외부에서 코드의 일부를 테스트하게 될 수 있습니다. 이러한 일이 발생하지 않도록 코드의 외부 부분을 조롱하여 코드가 실행될 수 있는 특정 환경을 시뮬레이션할 수 있습니다. 이렇게 하면 코드가 다른 조건에서 항상 예상대로 작동하도록 할 수 있습니다.

Jest로 조롱하기



다행스럽게도 Jest는 코드의 다른 부분을 조롱하는 것을 상당히 간단하게 만듭니다(일단 어떻게 수행되는지 파악한 후). 그리고 지금 사용할 수 있는 몇 가지 기본 방법을 다루겠습니다!

설정



두 개의 클래스가 있다고 가정하겠습니다. 현재 테스트 중인 클래스인 'ProductManager'와 API에서 제품을 가져오는 데 사용할 'ProductClient'입니다.

ProductsClient는 다음과 같이 보일 수 있습니다.

export class ProductsClient {
  async getById(id) {
    const url = `http://localhost:3000/api/products/{id}`;
    const response = await fetch(url);
    return await response.json();
  }
}

ProductManager는 다음과 같이 보일 수 있습니다.

export class ProductManager {
  async getProductToManage(id) {
    const productsClient = new ProductsClient();
    const productToManage = await productsClient.getById(id)
      .catch(err => alert(err));
    return productToManage;
  }
}

따라서 ProductManager는 제품을 가져와서 값을 반환하여 가져오는 동안 오류가 있으면 알려줍니다. 충분히 간단해 보이죠? 좋습니다. Jest로 ProductsClient를 조롱하여 ProductManager를 단위 테스트하는 방법을 살펴보겠습니다.

테스트 작성



내가 보여줄 첫 번째 방법은 Jest의 자동 조롱을 사용하는 것입니다. 조롱하려는 모듈을 가져오고 다음과 같이 jest.mock()을 호출하기만 하면 됩니다.

import { ProductsClient } from './ProductsClient';

jest.mock('./ProductsClient');

이제 ProductsClient 클래스(즉, getById())의 모든 메서드는 자동으로 조롱되고 '정의되지 않음'을 반환합니다. 이제 이것은 많은 용도에 완벽하게 적합할 수 있습니다. 그러나 우리의 경우에는 몇 가지 문제가 있습니다. 첫째, ProductClient가 항상 '정의되지 않음'을 반환하는 경우 ProductManager가 올바른 값을 반환하는지 어떻게 테스트할 수 있습니까? 그러나 더 중요한 것은 getById()에 대한 호출이 'undefined'를 반환하는 경우 'undefined'에 대한 메서드를 호출할 수 없기 때문에 .catch() 절에서 오류가 발생한다는 것입니다!

반환 값 조롱



이 문제를 해결하려면 어떻게 해야 합니까? 우리는 함수 반환 값을 조롱합니다. 기존 테스트가 다음과 같다고 가정해 보겠습니다.

it('should return the product', async () => {
  const expectedProduct = {
    id: 1,
    name: 'football',
  };
  const productManager = new ProductManager();
  const result = await productManager.getProductToManage(1); // Will throw error!

  expect(result.name).toBe('football');
});


ProductManager 클래스 내의 ProductClient에서 'getById'에 대한 호출이 'expectedProduct'로 확인되는 약속을 반환하도록 만들어야 합니다. 이렇게 하려면 ProductsClient의 'getById' 메서드에 모의 함수를 할당해야 합니다. 그러나 ES6 클래스 구문을 사용하고 있으므로 'ProductsClient.getById'에 할당하는 것만큼 간단하지 않으므로 객체의 프로토타입에 할당해야 합니다.

const mockGetById = jest.fn();
ProductsClient.prototype.getById = mockGetById;

이 작업이 완료되면 모의 함수가 반환해야 할 내용을 추가할 수 있습니다.

const mockGetById = jest.fn();
ProductsClient.prototype.getById = mockGetById;
mockGetById.mockReturnValue(Promise.resolve(expectedProduct));

이제 완성된 테스트 파일은 다음과 같아야 합니다.

import { ProductsClient } from './ProductsClient';
import { ProductManager } from './ProductManager';

jest.mock('./ProductsClient');

it('should return the product', async () => {
  const expectedProduct = {
    id: 1,
    name: 'football',
  };
  const productManager = new ProductManager();
  const mockGetById = jest.fn();
  ProductsClient.prototype.getById = mockGetById;
  mockGetById.mockReturnValue(Promise.resolve(expectedProduct));

  const result = await productManager.getProductToManage(1); 

  expect(result.name).toBe('football'); // It passes!
});


결론



Jest를 사용하여 클래스 메서드를 조롱하는 데 유용한 소개가 되었기를 바랍니다! 당신이 그것을 즐겼다면 나는 당신이 나에게서보고 싶은 다른 것들에 대한 당신의 생각과 제안을 듣고 싶습니다. 읽어 주셔서 감사합니다!

좋은 웹페이지 즐겨찾기