Logo

자바스크립트에서 Faker로 가짜 데이터 생성하기

제가 몇 년 전에 블로그에서 npm 패키지 저장소에 faker라는 이름으로 등록되어 있는 라이브러리를 소개해 드린 적이 있는데요. 안타깝게도 2022년에 faker를 유지보수하던 개발자가 불미스러운 일을 저질러 더 이상 사용하면 안 되는 라이브러리가 되었습니다. (오픈 소스 커뮤니티에 시사하는 바가 컸던 사건이므로 관심있으신 분은 관련 기사를 참고하시기 바랍니다.)

현재는 npm 패키지 저장소에 @faker-js/faker라는 패키지 이름으로 등록된 새로운 라이브러리가 예전에 faker 라이브러리를 대신하고 있는데요. 과거의 실수를 교훈 삼아 여러 명의 개발자가 공동으로 유지보수하는 형태로 운영이 되고 있습니다. 이번 포스팅에서는 얼마 전에 출시된 버전 8을 기준으로 Faker 라이브러리를 사용하여 어떻게 가짜 데이터를 생성할 수 있는지에 대해 다루려고 합니다.

가짜 데이터가 왜 필요할까?

Faker 사용법에 대해서 배우기 전에 먼저 소프트웨어 개발에서 가짜 데이터가 왜 필요한지 짚고 넘어가면 좋을 것 같아요.

시제품(prototype)을 개발하거나, 테스트를 작성하다보면 가짜 데이터가 필요할 때가 자주 있지요? 소규모 프로젝트라면 직접 가짜 데이터를 하드코딩(hard-coding)할 수도 있겠지만, 프로젝트의 규모가 커지게 되면 가짜 데이터를 생성하는데 들어가는 노력이 눈덩이처럼 불어날 수 있습니다. 그리고 현실에 충분히 있을 법한 가짜 데이터를 지어내야하는 것도 개발자 입장에서 불필요한 스트레스가 될 수 있고요.

Faker와 같은 가짜 데이터를 생성해주는 라이브러리를 사용하면 이러한 가짜 데이터 생성에 들어가는 비용을 획기적으로 줄일 수 있는데요. 함수 호출 한 번만으로 해당 비즈니스 도메인에 맞는 그럴듯한 가짜 데이터를 생성할 수 있기 때문에 개발 생산성과 개발자 경험을 크게 개선할 수 있습니다.

뿐만 아니라 데이터의 진위 여부가 중요하지 않은 개인 프로젝트나 코딩 연습을 할 때도 이러한 라이브러리를 정말 유용하게 사용할 수 있겠죠?

패키지 설치

npm i 또는 npm install 명령어를 사용하여 @faker-js/faker라는 이름의 패키지를 설치합니다. 대부분의 경우, 가짜 데이터를 실제품에서 사용하지는 않을 것이므로 -D 또는 --save-dev 옵션을 사용하여 개발 의존성으로 설치하셔야 할 것입니다.

$ npm i -D @faker-js/faker

패키지 임포트

@faker-js/faker 패키지로부터 faker를 named import로 불러옵니다.

import { faker } from "@faker-js/faker";

참고로 Faker는 다국어도 지원하는데요. 예를 들어, 한국어로 가짜 데이터를 생성하고 싶다면 다음과 같이 한국어용 faker를 불러오실 수 있습니다.

import { fakerKO as faker } from "@faker-js/faker";
import { faker } from "@faker-js/faker/locale/ko";

제가 직접 사용을 해보니 아직 한국어 지원이 많이 미흡하더라고요. 한국어로 설정해도 영어로 결과가 나오는 API도 많고 한국어로 결과가 나오더라도 어색한 많습니다.

Faker API 구조

Faker 라이브러리는 가짜 데이터를 생성하기 위한 수 많은 함수를 제공하고 있는데요. 서로 관련있는 함수들을 여러 범주로 나누어 놓았기 때문에 API가 faker.<범주>.<함수>() 구조로 이루어져 있습니다.

따라서 생성하려는 가짜 데이터가 어느 범주에 속하는지를 파악하시면 좀 더 쉽게 라이브러리를 사용할 수 있습니다. 예를 들어, 가짜 사용자 데이터를 생성할 때 필요한 함수는 faker.person 속성에 모여있고, 가짜 상품 데이터를 생성할 때 필요한 함수는 faker.commerce 속성에 모여있습니다.

가짜 사용자 정보 생성

어떤 서비스를 개발하든지 가짜 사용자 정보가 정말 자주 필요하죠? 특히 테스트 작성할 때요. faker.person 속성 아래에 모여있는 함수를 사용하면 가짜 사용자 데이터를 간편하게 생성할 수 있습니다.

faker.person.firstName(); // 'Claude'
faker.person.lastName(); // 'Mueller'
faker.person.fullName(); // 'Dr. Brad Schaden'
faker.person.jobTitle(); // 'Internal Division Orchestrator'
faker.person.sex(); // 'male'

가짜 인터넷 데이터 생성

인터넷에서 흔히 찾아볼 수 있는 이메일, 비밀번호, IP 주소, URL과 같은 데이터를 생성하기 위한 함수는 faker.internet 속성에 모여있습니다.

faker.internet.email(); // 'Claude_Mueller@hotmail.com'
faker.internet.password(); // '3PnJkjkr3mn0tBP'
faker.internet.ip(); // '38.70.50.205'
faker.internet.url(); // 'https://sniveling-script.org'

가짜 전화번호 생성

가짜 전화번호는 faker.phone 속성을 통해서 생성할 수 있는데요. 일반 전화번호 뿐만 아니라 IMEI 번호도 생성할 수 있습니다.

faker.phone.number(); // '568.567.7782'
faker.phone.imei(); // '12-188918-130546-7'

가짜 상품 정보 생성

전자 상거래 서비스를 개발하시면 가짜 상품 정보도 많이 필요하실텐데요. faker.commerce 속성을 통해서 상품 이름, 설명, 가격 등을 가짜로 생성해주는 유용한 함수를 사용할 수 있습니다.

faker.commerce.product(); // 'Mouse'
faker.commerce.productAdjective(); // 'Recycled'
faker.commerce.productDescription(); // 'Carbonite web goalkeeper gloves are ergonomically designed to give easy fit'
faker.commerce.department(); // 'Jewelery'
faker.commerce.price(); // '438.00'

가짜 문자열 데이터 생성

faker.string 속성에는 문자형의 가짜 데이터를 생성하기 위한 함수가 모여있습니다.

우선, 단순히 무작위 문자열을 얻고 싶다면 sample() 함수를 호출하면 됩니다.

faker.string.sample(); // '2OZmIYjhiq'

제한된 문자로만 이루어진 문자열을 얻기 위해서는 다음과 같이 다양한 함수를 사용할 수 있는데요. 이러한 함수들은 기본적으로는 길이가 1인 문자열을 제공하지만, 문자열 길이를 인자로 넘겨서 더 긴 문자열을 얻을 수도 있습니다.

faker.string.alpha(); // 'j'
faker.string.numeric(); // '7'
faker.string.alphanumeric(8); // 'rBMLMRg9'
faker.string.symbol(3); // ')$^'
faker.string.fromCharacters("xyz", 5); // 'zzxzx'

faker.string 속성에는 가짜 아이디가 필요할 때 아주 유용하게 쓸 수 있는 함수도 있는데요. 예전 많이 쓰이던 숫자형 아이디는 물론이고 최근에 많이 쓰이는 UUID나 Nano ID도 쉽게 생성할 수 있습니다.

faker.string.numeric(8); // '74640945'
faker.string.uuid(); // '4243cdf2-e150-487a-95bc-51808700c4e3'
faker.string.nanoid(); // 'C4_VEoMjzRr-8HHdVrU3_'

UUID와 NanoID 대한 자세한 설명은 아래 포스팅을 참고 바랍니다.

가짜 숫자형 데이터 생성

faker.number 속성을 통해서 정수, 소수, 이진수와 같은 다양한 숫자형 데이터를 가짜로 생성할 수 있습니다.

faker.number.int(); // 1725053848780800
faker.number.float(); // 0.49766366626136005
faker.number.binary(); // 1

숫자의 최대 크기를 제한하고 싶다면 인자로 최대값을 넘기면 됩니다.

faker.number.int(100); // 61

가짜 불리언 생성

가짜 불리언을 생성하실 때는 faker.datatype.boolean() 함수를 호출하면 됩니다.

faker.datatype.boolean(); // true
faker.datatype.boolean(); // true
faker.datatype.boolean(); // false

참고로 faker.datatype 속성에는 다른 기본형 데이터를 생성하기 위한 함수도 있는데요. 하지만 V8에서 모두 deprecated, 즉 폐기 예정이기 때문에 가급적 쓰시지 말기를 추천드립니다.

대신에 위에서 다룬 것처럼, 가짜 문자형 데이터가 필요하시다면 faker.string 속성을 쓰시면 되고, 가짜 숫자형 데이터가 필요하시다면 faker.number 속성을 쓰시기 바랍니다.

가짜 날짜 데이터 생성

가짜 데이터를 논할 때 날짜도 빼놓을 수 없는데요. faker.date 속성에는 날짜 데이터를 가짜로 생성하기 위한 함수가 들어 있습니다.

우선, 그냥 무작위 날짜를 생성하려면 anytime() 함수를 호출하면 되고요.

faker.date.anytime(); // 2023-01-14T18:35:51.237Z

몇 달 이상의 먼 과거는 past() 함수를 사용하여 생성하고, 몇 일 내의 가까운 과거는 recent() 함수를 사용합니다. 반대로 가까운 미래는 soon() 함수, 먼 미래는 future() 함수를 사용하여 생성합니다.

faker.date.past(); // 2023-02-27T07:38:34.596Z
faker.date.recent(); // 2023-08-27T08:14:45.903Z
faker.date.soon(); // 2023-08-28T18:48:17.902Z
faker.date.future(); // 2024-02-03T17:40:18.962Z

between() 함수를 사용하면 특정 기간 내에서 무작위 날짜를 생성할 수 있습니다.

faker.date.between({
  from: new Date("2000"),
  to: new Date("2002"),
}); // 2000-05-20T00:01:02.041Z

가짜 텍스트 생성

Faker는 faker.lorem 속성을 통해서 lorem ipsum을 기반으로 하는 무작위 텍스트 생성도 지원하는데요. 특히 시제품을 만들 때 유용합니다.

예를 들어, 무작위 단어, 문장, 문단을 생성해보겠습니다.

faker.lorem.word(); // ratione
faker.lorem.sentence(); // Error facere iure iste porro impedit.
faker.lorem.paragraph(); // Nulla tempora sed incidunt nesciunt quod facere sapiente quia. Dicta corporis aut blanditiis odio fuga veniam expedita maxime ipsam. Molestias ipsa blanditiis.

블로그 포스팅의 URL로 많이 사용되는 소위 slug도 어렵지 않게 만들 수 있습니다.

faker.lorem.slug(); // ratione-ducimus-error

기타 도우미 함수

마지막으로 소개해드리고 싶은 Faker의 API는 바로 faker.helpers인데요.

우선 배열에서 무작위로 값을 선택하기 위한 arrayElement()arrayElements() 함수가 상당히 유용합니다.

faker.helpers.arrayElement(["To do", "Doing", "Done"]); // To do
faker.helpers.arrayElements(["To do", "Doing", "Done"]); // [ 'Done', 'Doing' ]

이러한 도우미 함수가 없었다면 다음과 같이 복잡한 코드를 스스로 작성했어야 할 것입니다. 😬

["To do", "Doing", "Done"][Math.floor(Math.random() * array.length)]; // To do

shuffle() 함수를 이용하면 배열 내의 원소를 무작위로 섞을 수 있습니다.

faker.helpers.shuffle(["a", "b", "c"]); // [ 'b', 'c', 'a' ]

객체에서 무작위로 키 또는 값을 선택하거나 키와 값의 동시에 선택할 수도 있습니다.

faker.helpers.objectKey({ a: 1, b: 2, c: 3 }); // 'a'
faker.helpers.objectValue({ a: 1, b: 2, c: 3 }); // 2
faker.helpers.objectEntry({ a: 1, b: 2, c: 3 }); // ['b', 2]

enumValue() 함수는 이넘(Enum)에서 하나의 맴버를 선택할 때 유용합니다.

enum HttpStatus {
  Ok = 200,
  Created = 201,
  BadRequest = 400,
  Unauthorized = 401,
}
faker.helpers.enumValue(HttpStatus) // 200

가짜 데이터 고정

스냅샷(snapshot) 테스트를 작성하실 때는 테스트가 실행될 때 마다 가짜 데이터가 변하면 곤란한데요. 이 때는 faker.seed() 함수를 사용하여 고정된 시드(seed) 값을 넘겨주시면 항상 동일한 가짜 데이터의 생성을 보장받을 수 있습니다.

test("user snapshot", () => {
  faker.seed(101);
  expect({
    name: faker.person.fullName(),
    email: faker.internet.email(),
    phone: faker.phone.number(),
  }).toMatchSnapshot();
});

스냅샷 이외에 테스트 케이스에서는 원래대로 가변 데이터가 생성되길 원하다면 afterEach() 함수를 통해 인자없이 faker.seed()를 호출해주시면 됩니다.

afterEach(() => {
  faker.seed();
});

마치면서

지금까지 Faker 라이브러리의 풍부한 API를 사용하여 여러가지 가짜 데이터를 생성해보았습니다.

사실 본 포스팅에서 Faker로 만들어본 가짜 데이터는 빙산의 일각일 뿐이며 이 보다 훨씬 더 다채로운 가짜 데이터도 만드실 수 있습니다. 너무 방대하여 본 포스팅에서 미처 다루지 못한 Faker의 다른 API에 대해서는 공식 API 레퍼런스 문서를 참고하시길 바랍니다.

다음 포스팅에서는 실제로 테스트 코드를 작성할 때 Faker를 어떻게 활용하는지에 대해서 다루겠습니다.