비교

Mock Service Worker와 유사한 도구들과의 비교.

작업에 적합한 도구를 선택하는 것은 매우 중요합니다. 아래에서 Mock Service Worker와 다른 오픈소스 API 모킹 라이브러리 간의 포괄적이고 공정한 비교를 제공하기 위해 최선을 다했습니다.

비교 기준

좋은 비교는 명확하게 정의된 기준에서 시작합니다. MSW와 대안들을 비교할 때 사용한 기준은 다음과 같습니다 (개발자 관점에서 작성):

  • 지원하는 API 타입. 어떤 종류의 API를 모킹할 수 있는가?
  • 환경. 어떤 환경에서 사용할 수 있는가?
  • 구현 방식. 요청 가로채기를 어떻게 구현했는가?
  • 통합. 프로젝트에 통합하는 데 얼마나 많은 노력이 필요한가?
  • 정의 방식. 모의 응답을 어떻게 정의하는가?

Nock

Nock은 Node.js용 HTTP 서버 모킹 및 기대값 설정 라이브러리입니다.

Nock은 Node.js에서 API 모킹과 어설션을 결합하는 데 탁월한 라이브러리입니다. Mock Service Worker는 내장된 어설션 기능을 제공하지 않지만, 브라우저와 Node.js에서 동일한 모킹을 원활하게 재사용할 수 있으며, 퍼스트클래스 GraphQL 지원과 표준 기반의 요청/응답 처리를 제공합니다.

API 지원

API 타입NockMock Service Worker
REST API
GraphQL API
WebSocket API

지원 환경

환경NockMock Service Worker
Node.js
브라우저

통합

NockMock Service Worker
코드 변경 없이 사용 가능코드 변경 없이 사용 가능
특정 요청 클라이언트(예: axios)를 가로채기 위해 추가 어댑터 필요추가 설정 없이 모든 요청 클라이언트와 함께 작동

Definition

Nock

Nock는 _메서드 체이닝_을 사용해 요청을 가로채고 모의 응답을 선언합니다:

nock('https://api.example.com')
  .get('/user')
  .reply(200, { id: 1, name: 'John' })

Mock Service Worker

import { bypass } from 'msw'
 
http.post('/fruits', async ({ request }) => {
  const response = await fetch(bypass(request))
  const json = await response.json()
  json.push({ name: 'Mock Service Worker' })
 
  return HttpResponse.json(json, response)
})

MSW에서 route.continue() 대신 사용할 수 있는 방법은 응답 리졸버에서 아무것도 반환하지 않는 것입니다. 하지만 우리는 요청을 메서드(POST)와 경로(/fruits)로 좁힐 수 있기 때문에, 이 요청 핸들러는 다른 요청에 대해 신경 쓸 필요가 없습니다.

MSW는 커스텀 bypass() 함수를 사용하여 주어진 Request 인스턴스를 감싸서, 다른 요청 핸들러의 영향을 받지 않도록 합니다.

JSON Server

JSON Server는 JSON 파일을 기반으로 실제 HTTP 서버를 생성할 수 있게 해줍니다.

JSON Server는 추상적인 응답 정의 형식을 사용하는 실제 HTTP 서버입니다. 이는 여러분이 실행하고 유지해야 하는 서버를 의미합니다. Mock Service Worker는 어떤 서버도 생성하지 않기 때문에 초기화 비용이 없습니다. 또한 Mock Service Worker는 TypeScript와 같은 언어를 사용하여 실제 백엔드 구현에서 모의 데이터를 생성함으로써 더 안전한 모의 정의를 가능하게 합니다.

API 지원 현황

API 타입JSON 서버Mock Service Worker
REST API
GraphQL API
WebSocket API

지원 환경

환경JSON 서버Mock Service Worker
Node.js
브라우저1

1—JSON 서버는 실제로 브라우저에서 실행되지 않습니다. 독립형 서버이기 때문에 시스템 어디에서나 요청할 수 있습니다.

Integration_Q5V2MVyb6wRowkRHzFGxNm

JSON 서버Mock Service Worker
모의 서버에서 리소스를 요청하도록 코드를 변경해야 함.코드 변경 없이 사용 가능.
추가 설정 없이 모든 요청 클라이언트와 함께 작동.추가 설정 없이 모든 요청 클라이언트와 함께 작동.

Definition_BvcXBvPNQxC7pcCCjhE5dC

JSON Server

JSON Server는 리소스 중심의 라우트 형식을 사용하여 요청 경로를 암묵적으로 생성하고 모의 응답을 설명합니다.

{
  "posts": [
    { "id": 1, "title": "json-server" },
    { "id": 2, "title": "mock-service-worker" }
  ]
}

이렇게 하면 설명된 리소스를 기반으로 GET /postsDELETE /posts/:index와 같은 서버 측 라우트가 자동으로 생성됩니다. 이러한 라우트의 특성은 정적이며, 더 복잡한 네트워크 동작을 구현하려면 추가적인 추상화가 필요합니다.

Mock Service Worker_Y3Kvu9fneg2pjcFkHN7D6C

MSW는 서버 사이드 라우팅을 모델로 한 인터셉션 API를 제공하며, Fetch API 명세에 따라 요청과 응답을 처리합니다. 이때 일반적으로 자바스크립트에서 사용하는 동일한 클래스를 사용합니다:

http.get('/posts', () => {
  return HttpResponse.json([
    { id: 1, title: 'json-server' },
    { id: 2, title: 'mock-service-worker' },
  ])
})

MSW를 사용할 때는 http.get('/posts')http.delete('/posts/:index')와 같은 서버 사이드 작업을 명시적으로 정의해야 합니다. MSW는 명시성을 우선시하며, 프로그래밍 방식의 요청 해결을 활용하여 더 복잡한 네트워크 동작을 가능하게 합니다.

Mirage

Mirage는 백엔드 서비스에 의존하지 않고도 완전히 동작하는 자바스크립트 애플리케이션을 구축하고 테스트하며 공유할 수 있게 해주는 API 모킹 라이브러리입니다.

Mirage는 더 복잡한 서버 동작을 에뮬레이트하기 위해 데이터 모델링을 중심으로 설계되었습니다. 반면 Mock Service Worker는 내장된 데이터 모델링 기능을 제공하지 않으며, 대신 @mswjs/data라는 별도의 패키지로 이를 제공합니다. 이렇게 하면 필요할 때 모델링 기능을 추가할 수 있습니다.

API 지원_V5YUdQJWC56bHj2KqGrwg7

API 타입MirageMock Service Worker
REST API
GraphQL API
WebSocket API

지원 환경

환경MirageMock Service Worker
Node.js
브라우저

구현

환경MirageMock Service Worker
브라우저fetchXMLHttpRequest를 몽키 패칭(monkey-patch)하여 사용 (pretender 사용).서비스 워커를 사용하여 브라우저 수준에서 요청을 가로챔.

Integration_E9uewouvTYCzqDUiMGKES3

MirageMock Service Worker
코드 변경 없이 사용 가능.코드 변경 없이 사용 가능.
추가 설정 없이 모든 요청 클라이언트와 호환.추가 설정 없이 모든 요청 클라이언트와 호환.

Definition_bXzPPNjU5qn2WssRUTV55N

Mirage

Mirage는 서버와 유사한 라우트와 모의 응답을 정의하기 위해 라우트 핸들러 형식을 사용합니다.

createServer({
  routes() {
    this.get('/movies', () => {
      return ['Interstellar', 'Inception', 'Dunkirk']
    })
  },
})

Mirage는 더 복잡한 데이터 관계를 모델링할 수 있도록 메모리 내 데이터베이스를 제공합니다.

createServer({
  models: {
    movie: Model.extend({
      castMembers: hasMany(),
    }),
    castMember: Model.extend({
      movie: belongsTo(),
    }),
  },
  routes() {
    // 데이터를 응답하는 라우트 핸들러
  },
})

Mock Service Worker_YrsqJPpuZwaEAyuKY6VoFT

MSW는 서버 측 라우팅을 모델로 한 인터셉션 API를 제공하며, Fetch API 명세에 따라 요청과 응답을 처리합니다. 이때 일반적으로 자바스크립트에서 사용하는 동일한 클래스를 활용합니다:

http.get('/movies', () => {
  return HttpResponse.json(['Interstellar', 'Inception', 'Dunkirk'])
})

MSW는 기본적으로 데이터 모델링 기능을 제공하지 않지만, @mswjs/data와 같은 생태계 패키지를 활용해 데이터 중심의 API 모킹 방식을 선택할 수 있습니다.

import { factory, primaryKey, oneOf, manyOf } from '@mswjs/data'
 
// 데이터 모델링
const db = factory({
  movie: {
    id: primaryKey(randomUuid),
    title: String,
    castMembers: manyOf('castMember'),
  },
  castMember: {
    id: primaryKey(randomUuid),
    name: String,
    movie: oneOf('movie'),
  },
})
 
// 모델을 기반으로 요청 핸들러 생성
// - GET /movies
// - GET /movies/:id
// - POST /movies
// - ...
db.toHandlers('rest')
 
// GraphQL 쿼리도 포함!
// - query ListMovies
// - query GetMovie
// - mutation AddMovie
// - ...
db.toHandlers('graphql')

Cypress - cy.intercept()

Cypresscy.intercept() API를 통해 API 모킹 기능을 제공하는 엔드투엔드 테스트 프레임워크입니다.

API 지원 비교표

API 타입cy.intercept()Mock Service Worker
REST API
GraphQL API1
WebSocket API

1—커스텀 별칭을 통해 GraphQL 요청을 처리할 수 있지만, 여전히 많은 추가 설정이 필요합니다. Cypress는 GraphQL을 퍼스트클래스로 지원하기보다는 HTTP 처리(웹에서 GraphQL이 주로 HTTP를 통해 구현되기 때문)를 통해 GraphQL API 모킹을 구현합니다.

지원 환경_GfVivJ7fwqc2JZYt8h4rAq

API 타입cy.intercept()Mock Service Worker
Node.js1
브라우저

1—Cypress는 브라우저 테스트 프레임워크이므로, 통합 테스트나 백엔드 애플리케이션과 같은 Node.js 프로세스에서는 cy.intercept() 모킹을 사용할 수 없습니다.

Implementation_DX6taHN8c66gTPp9GQwhcV

환경cy.intercept()Mock Service Worker
브라우저Cypress 런타임의 일부로 생성된 커스텀 서버를 통해 나가는 요청을 라우팅하기 위해 브라우저 전체 HTTP 프록시를 사용합니다.브라우저 수준에서 요청을 가로채기 위해 Service Worker를 사용합니다.

Integration_LoWuFoKKqfcHGy2Udas7JY

cy.intercept()Mock Service Worker
코드 변경 없이 사용 가능. Cypress에 기본 내장되어 있음.코드 변경 없이 사용 가능.
추가 설정 없이 모든 요청 클라이언트와 함께 작동.추가 설정 없이 모든 요청 클라이언트와 함께 작동.

Definition_myeZmXhCwWja7NqREQWtpi

cy.intercept()

Cypress는 커스텀 매처 시그니처와 라우트 핸들러 함수를 사용하여 요청을 가로채고 처리합니다. 더 세부적인 요청 제어를 위해 req.reply(), req.continue(), req.redirect()와 같은 커스텀 메서드를 활용합니다.

cy.intercept('POST', '/users', {
  statusCode: 201,
  body: req.body,
  delay: 100,
})

Mock Service Worker_432rVbdnpKhfve7xiEPNvQ

MSW는 서버 측 라우팅을 모델로 하여 인터셉션 API를 설계했으며, Fetch API 명세에 따라 요청과 응답을 처리합니다. 이때 일반적으로 자바스크립트에서 사용하는 동일한 클래스를 사용합니다:

import { http, delay } from 'msw'
 
http.post('/users', async ({ request }) => {
  // 일반적으로 하듯이 요청 본문을 읽습니다.
  const user = await request.json()
 
  // 응답 리졸버 실행 흐름을 제어합니다.
  // 아래의 "delay" Promise와 같이 Promise를 사용합니다.
  await delay(100)
 
  // 일반적으로 하듯이 응답을 구성합니다.
  return HttpResponse.json(user, { status: 201 })
})

MSW는 passthrough()bypass() API를 통해 요청에 대한 더 세밀한 제어를 제공하며, 이는 내부적으로 여전히 의미론적인 HTTP 응답을 생성합니다.

Playwright - page.route()

Playwrightpage.route() API를 통해 브라우저 테스트 도구로서 API 모킹 기능을 제공합니다.

API 지원_Sns6x7e5vTJULjVgfWhzoF

API 타입page.route()Mock Service Worker
REST API
GraphQL API1
WebSocket API

1—GraphQL 요청은 HTTP 요청이므로 page.route()로 처리할 수 있지만, Playwright는 GraphQL API 모킹을 위한 퍼스트클래스 지원을 제공하지 않습니다.

지원 환경_kAARhUPZAPuwEUJa6YRPpZ

API 타입page.route()Mock Service Worker
Node.js1
브라우저

1—Playwright를 사용하면 테스트를 Node.js로 작성하지만,
Playwright 자체(및 page.route())는 생성된 브라우저의 트래픽에만 영향을 미치며,
Node.js 프로세스에는 영향을 주지 않습니다.

Implementation_8eFvKUf8ChratpwVwH4FYa

환경page.route()Mock Service Worker
브라우저Chrome DevTools Protocol를 사용하여 브라우저 수준에서 요청을 가로챕니다.Service Worker를 사용하여 브라우저 수준에서 요청을 가로챕니다.

Integration_HSH8WWwZs2X5PNveHPakYw

page.route()Mock Service Worker
코드 변경 없이 사용 가능. Playwright에서 기본 제공.코드 변경 없이 사용 가능.
추가 설정 없이 모든 요청 클라이언트와 호환.추가 설정 없이 모든 요청 클라이언트와 호환.

Definition_KmtWoenDAJizzqcheP7BQy

page.route()

Playwright의 page.route() 함수는 route.fulfill()route.continue()와 같은 커스텀 메서드를 사용하여 요청을 더 세밀하게 제어할 수 있게 해줍니다.

page.route('/fruits', async (route) => {
  const request = route.request()
 
  if (request.method === 'POST') {
    const response = await route.fetch()
    const json = await response.json()
    json.push({ name: 'Playwright' })
 
    return route.fulfill({ response, json })
  }
 
  route.continue()
})