Server/API Mocking

[API Mocking] API Mocking Server 구축 (3) - Jest

aeeazip 2024. 8. 16. 17:01

목차


1. API Mocking 정의

2. Jest
3. 사용 방법

4. 테스트

 

 

 

 

 

1. API Mocking 정의


API Mocking 정의는 1편에 작성해두었으니 참고하길 바란다.

 

https://aeeazip.tistory.com/55

 

[API Mocking] API Mocking Server 구축 (1) - MSW

목차1. API Mocking 정의2. MSW3. 사용 방법4. 테스트    1. API Mocking 정의  프론트엔드 개발에서 데이터를 사용한 개발은 백엔드 API 개발에 의존하며 병렬적으로 진행된다. API에 종속적인 

aeeazip.tistory.com

 

 

 

 

 

2. Jest


JavaScript의 테스팅 프레임워크로, 주로 유닛 테스트와 통합 테스트를 작성할 때 사용한다.

Jest 자체로는 모킹(mocking) 기능을 내장하고 있으며, 이를 통해 API 요청을 가로채고 가상의 응답을 반환하여 테스트할 수 있다. 또한 테스트를 병렬 실행하여 테스트 시간이 감소한다.

 

Http 요청을 모킹하는 경우 axios, fetch와 같은 HTTP 클라이언트를 모킹하여 네트워크 요청에 대한 응답을 제어할 수 있다.

 

 

 

 

3. 사용 방법


Jest를 사용하기 위해서는 먼저 jest 라이브러리를 설치해야 한다.

 

$ npm install jest

 

jest를 설치했다면, 이제 코드를 작성할 차례다.

먼저 api.js 파일이다.

// src/jest/api.js

import { errResponse } from '../config/response.js'

// [GET] 채널 리스트 조회
export async function fetchChannelList() {
  const url = 'http://localhost:3001/jest/profile/channel-list-info'
  const response = await fetch(url)

  if (!response.ok) {
    return errResponse({ respCode: 400, respMsg: 'REQUEST_CHANNEL_LIST_FAIL' })
  }

  const data = await response.json()
  return response({ respCode: 200, respMsg: '응답성공' }, data)
}

// [GET] 활동 사용자 수 조회
export async function fetchActiveUserInfo(searchFromDate, searchToDate) {
  const url = `http://localhost:3001/jest/dashboard/active-user-info?searchFromDate=${searchFromDate}&searchToDate=${searchToDate}`
  const response = await fetch(url)

  if (!response.ok || !searchFromDate || !searchToDate) {
    return errResponse({
      respCode: 400,
      respMsg: 'REQUEST_ACTIVE_USER_INFO_FAIL',
    })
  }

  const data = await response.json()
  return response({ respCode: 200, respMsg: '응답성공' }, data)
}

 

실제 jest 테스트를 수행할 api.test.js 파일이다.

 

// src/jest/api.test.js

/* eslint-disable no-undef */
import { fetchChannelList, fetchActiveUserInfo } from './api'
import { response, errResponse } from '../config/response.js'

// 모듈 모킹
jest.mock('./api', () => ({
  fetchActiveUserInfo: jest.fn(),
  fetchChannelList: jest.fn(),
}))

// // [GET] 채널 리스트 조회 테스트
test('채널 리스트 조회 테스트', async () => {
  const channelListData = {
    totalCnt: 3,
    list: [
      {
        imgUrl:
          'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg',
        appSortIndex: 1,
        appKorNm: '채널첫번쨰등록',
        appType: 'C0A801CD0190BFD02932D2D118A1B822',
        appOsType: 'T',
      },
      {
        imgUrl:
          'https://health.chosun.com/site/data/img_dir/2023/07/17/2023071701753_0.jpg',
        appSortIndex: 1,
        appKorNm: '두번째채널등록',
        appType: 'C0A801CD0190BFD0B2FEF8F72EFD85A4',
        appOsType: 'A',
      },
    ],
  }
  const expectedResponse = response(
    { respCode: 200, respMsg: '응답성공' },
    channelListData,
  )

  fetchChannelList.mockImplementation(() => {
    return Promise.resolve(expectedResponse)
  })

  // fetchChannelList를 호출하여 결과를 확인
  const result = await fetchChannelList()
  expect(result).toEqual(expectedResponse)

  console.log('Test Result:', result)
})

// [GET] 활동 사용자 수 조회 테스트
test('활동 사용자 수 조회 테스트', async () => {
  const searchFromDate = '2024-08-06'
  const searchToDate = '2024-08-07'
  const activeUserData = {
    setActiveCnt: 2,
    newInstallCnt: 2,
    clickCnt: 1,
    setNotiCnt: 2,
  }
  const expectedResponse = response(
    { respCode: 200, respMsg: '응답성공' },
    activeUserData,
  )

  fetchActiveUserInfo.mockImplementation((from, to) => {
    if (from === searchFromDate && to === searchToDate) {
      return Promise.resolve(expectedResponse)
    }
    return Promise.reject(
      errResponse({ respCode: 400, respMsg: 'REQUEST_ACTIVE_USER_INFO_FAIL' }),
    )
  })

  // fetchActiveUserInfo를 호출하여 결과를 확인
  const result = await fetchActiveUserInfo(searchFromDate, searchToDate)
  expect(result).toEqual(expectedResponse)

  console.log('Test Result:', result)
})

 

반환 타입을 공통화하기 위해 response.js 파일을 생성해주었고 내용은 다음과 같다.

 

// src/config/response.js

export const response = (data) => {
  return {
    respCode: 200,
    respMsg: '응답성공',
    data: data,
  }
}

export const paramErrResponse = () => {
  return {
    respCode: 400,
    respMsg: 'Parameter Error',
  }
}

export const errResponse = ({ respCode, respMsg }) => {
  return {
    respCode: respCode,
    respMsg: respMsg,
  }
}

 

 

 

 

 

4. 테스트


Jest는 테스트 환경에서만 동작하기 때문에 

 

$ yarn test

 

위의 명령어를 입력하면 작성한 테스트 api가 병렬적으로 실행되면서 결과를 리턴한다.

 

실행 결과