Goでダミーデータを作る

# はじめに

プロジェクトをしているとダミーデータを作らないといけない時がそれなりにありますよね！

**1. テストデータの生成:** ソフトウェアやアプリケーションのテストを行う際に、実際のデータを使用するとプライバシーやセキュリティの問題が感じられるとき。


**2. データのマスキング:** プライバシーやセキュリティの観点から、本物のデータを使用する際には個人情報や機密情報を適切に保護する必要があるとき。

**3. プロトタイプの作成:** ソフトウェアやアプリケーションの開発段階では、リアルなデータを使用せずにプロトタイプのデータを使用して実行するとき。

こんな時に役立つのは[gofekit](https://github.com/brianvoe/gofakeit)です！

## インストール
```
go get github.com/brianvoe/gofakeit/v6
```

## gofekitの主な機能
### 1. ランダムな値の生成:


**ランダムな名前や姓、ユーザー名の生成:** gofakeit.Name(), gofakeit.FirstName(), gofakeit.LastName(), gofakeit.Username()...
**ランダムなメールアドレスの生成:** gofakeit.Email()
**ランダムな住所の生成**: gofakeit.Address(), gofakeit.Street(), gofakeit.City(), gofakeit.Country()
**ランダムな電話番号の生成:** gofakeit.Phone()
**ランダムな日付や時間の生成:** gofakeit.Date(), gofakeit.Time(), gofakeit.DateRange(), gofakeit.Timezone()


### 2.偽のデータの生成:
**ランダムな文章の生成:** gofakeit.Sentence(), gofakeit.Paragraph()
**ランダムな数字の生成:** gofakeit.Number(), gofakeit.Float64()
**ランダムなブール値の生成:** gofakeit.Bool()
**ランダムなUUIDの生成:** gofakeit.UUID()
**ランダムな色の生成:** gofakeit.Color()


### 3.データのカスタマイズ:
**カスタムデータの生成:** gofakeit.Struct() - 構造体に基づいたカスタムデータを生成します。
**オプションの設定:** 一部の関数ではオプション構造体を使用して生成の仕方をカスタマイズできます。

その他にも紹介できないくらい沢山のデータを作成できます。githubのREADMEに書いてあるので是非見てみてください！
もし使い方が分からない関数は[ソースコード](https://github.com/brianvoe/gofakeit/tree/master)に`[name]_tast.go`ファイルを見ると実際に使用している所が確認できるのでそこから確認してみてください！！



## 使ってみる

### ランダムな値の生成
```go:ランダムな値の生成
package main

import (
	"fmt"

	"github.com/brianvoe/gofakeit/v6"
)

func main() {
	// ランダムな名前の生成
	name := gofakeit.Name()
	fmt.Println("名前:", name)

	// ランダムな住所の生成
	address := gofakeit.Address()
	fmt.Println("住所:", address)

	// ランダムな電話番号の生成
	phone := gofakeit.Phone()
	fmt.Println("電話番号:", phone)

	// ランダムな日付の生成
	date := gofakeit.Date()
	fmt.Println("日付:", date)
}

```
[PlayGroundで実行確認](https://go.dev/play/p/zkIAP8K5qqK)

この例では、`gofakeit.Name()`を使用してランダムな名前を生成し、`gofakeit.Address()`を使用してランダムな住所を生成します。また、`gofakeit.Phone()`を使用してランダムな電話番号を生成し、`gofakeit.Date()`を使用してランダムな日付を生成しています。

### 偽のデータの生成

```go:偽のデータの生成
package main

import (
	"fmt"

	"github.com/brianvoe/gofakeit/v6"
)

func main() {
	// ランダムな文章の生成
	sentence := gofakeit.Sentence(5) // 5つの単語からなるランダムな文章を生成
	fmt.Println("文章:", sentence)

	// ランダムな数字の生成
	number := gofakeit.Number(1, 100) // 1から100までのランダムな数字を生成
	fmt.Println("数字:", number)

	// ランダムなブール値の生成
	boolean := gofakeit.Bool()
	fmt.Println("ブール値:", boolean)

	// ランダムなUUIDの生成
	uuid := gofakeit.UUID()
	fmt.Println("UUID:", uuid)

	// ランダムな色の生成
	color := gofakeit.Color()
	fmt.Println("色:", color)
}

```
[PlayGroundで実行確認](https://go.dev/play/p/m9pru5gOVKF)
この例では、`gofakeit.Sentence()`を使用して5つの単語からなるランダムな文章を生成し、`gofakeit.Number()`を使用して1から100までのランダムな数字を生成します。また、`gofakeit.Bool()`を使用してランダムなブール値を生成し、`gofakeit.UUID()`を使用してランダムなUUIDを生成します。最後に、`gofakeit.Color()`を使用してランダムな色を生成しています。

### データのカスタマイズ

```go:データのカスタマイズ
package main

import (
	"fmt"

	"github.com/brianvoe/gofakeit/v6"
)

type Person struct {
	Name    string
	Age     int
	Country string
}

func main() {
	// カスタムデータの生成
	var person Person
	gofakeit.Struct(&person) // ランダムな値でPerson構造体を生成

	fmt.Println("名前:", person.Name)
	fmt.Println("年齢:", person.Age)
	fmt.Println("国籍:", person.Country)
}

```
[PlayGroundで実行確認](https://go.dev/play/p/aZk919c1di_u)

この例では、`gofakeit.Struct()`でランダムな値でPerson構造体を生成することができます。

## 応用して使ってみる

### ランダムなデータの生成と保存
gofakeitを使用して大量のランダムなデータを生成し、それをファイルに保存することができます。たとえば、CSV形式でデータを保存する場合は、encoding/csvパッケージを使用してファイルに書き込むことができます。

```go:ランダムなデータの生成と保存
package main

import (
	"encoding/csv"
	"log"
	"os"
	"strconv"

	"github.com/brianvoe/gofakeit/v6"
)

type Person struct {
	Name    string
	Age     int
	Country string
}

func main() {
	// ランダムなデータの生成
	var people []Person
	for i := 0; i < 100; i++ {
		var person Person
		gofakeit.Struct(&person)
		people = append(people, person)
	}

	// データの保存（CSV形式）
	file, err := os.Create("data.csv")
	if err != nil {
		log.Fatal(err)
	}
	defer file.Close()

	writer := csv.NewWriter(file)
	defer writer.Flush()

	// ヘッダ行の書き込み
	writer.Write([]string{"Name", "Age", "Country"})

	// データ行の書き込み
	for _, person := range people {
		writer.Write([]string{person.Name, strconv.Itoa(person.Age), person.Country})
	}
}

```

<details>
<summary>作成製されたdata.csv</summary>

```csv:data.csv
Name,Age,Country
MpOCaGjlgQ,-8857053704176880217,FtvuppHQ
xEik,1428625218799510694,NxMPmITn
mTcoYYany,-4967573933788291257,FLBOK
hSohlvx,4415025737934560353,PBXnhz
vJtwYRehoa,-5679333303460995842,zUMUBH
fXpbu,-1429591177531518003,BqJJXD
GpSS,2893285134195933046,kJNdCW
AvMfHShpUm,2484935894133080211,gOnE
TLqRwweq,4168454270398848697,ebJoyCTG
NYgJMmmtI,-5205956506546033104,kBGMmZS
xPWQebK,7187154572192037266,nViELm
eHgzeU,1855163510605491424,ltWDggL
vVDu,-4720160210558657764,nqMZG
OnAoSTYiju,-6873591542607314186,CmtjM
rHoQBSOaub,-6810459787165213895,mUTJK
IbkIBY,-6364787081742139054,tZEIxIccAh
YTCkvYD,3574441095334435377,jkRRqP
WXUmOrKtl,6612187665544964176,xQjN
PwRCuksLwE,-4737360748110943740,ilxj
CDqKynj,-914825154805440192,AalZu
MLESZAXOi,-2825600510807310014,tcmXqw
isWMH,7648238569728334377,anlXQtQpJi
rpiiRQX,-4576370482996212184,xCOFyzXkC
JZgJTCfj,-7192927420542168564,igkbquAs
bROyhSB,501701241550557058,oRpkTKomBp
YCyhkluyx,5008271320915095605,Ihtgzh
nTTxcBI,4818393489197449663,jEpGKokv
JHON,-7662303449487256156,AmdqsD
FPfaFHhaY,-7246419268886130333,bpxfLykGW
ewGfDVmg,-3288436124678843402,egCjO
rUdilRCWXG,-4903367926629340289,PABNeuwEN
cWnPZbkf,-6769302036087275509,GvmtLeZ
CQCXpgnrB,-2499835018255016500,eJCsKpa
fjzpUmrN,6262414393095156297,ZNGoAxU
ePCJwIAqmx,-1041102298507432942,GkdKgztJc
FaTTPngURO,-6612200165910232359,XcmRgZNms
lphfDue,-2301735572358601332,bBnGRXZiXl
KlBlvSE,-4041359666707600166,quPc
qKuFTSDzR,5381253624532599424,jzjtHxVQR
kGllb,7653530268278739611,JSsPOp
YtWtdu,7426611283550164905,bcWi
TsRx,7342540806888286319,FYUgJeN
Dwcbbk,-4520817868389301001,YgjTuLC
jhQjSp,1382906468655481233,JBIP
FIzK,-9111400064507123744,Tsuot
eStE,116932630926348519,dPYuL
VrpepMm,-7451380745659022790,TdHmU
MGebz,-2136446382219426801,NuhXuJvTL
TfggBAj,-682081076736617476,OAxR
iMVr,-3732601536216409498,hEqcuAaGD
Wmtt,-9052497154425583815,GitAj
OsNiV,-2697389313398588546,EwicR
zqBdNMIYM,7267506281211849549,uMpUp
lkFCf,4625927765304520000,ihvrOIePI
DccD,-6755688038193328976,whoPRy
irqbJzR,-8331747969522153110,gBXbAeU
bQcwlA,-8762851075307362537,qNfwRuhE
jMOGkEND,-3568980360129704305,MUzQ
qMTCoIgYY,1854061591338607032,ihbvmwB
ZYYQRs,795032381946592752,wBOydqd
VqxNKHons,7316012630879186848,AvXL
AGeLrHGi,-1322238184158983568,ELweQ
EzNsk,2674330086932373144,QPSyPDayvm
uMqGgyUyg,-5439411789166825918,TmOduriq
TVsW,4551838798695305151,OSNaa
qKaNfC,-5823502204665307458,gChLREuoXC
hVznAv,1162969135632294965,FIWBEO
ikINNyTr,-4966103508811915966,XiPIOEjzLL
tPqnCxeQ,-3193239727216544751,woNIX
hiBbPtP,2666859979979719564,CUzg
jjMs,3118440141882332643,HScFJkn
UtwIEPNZw,8984072974128248387,bHTPTgjmwM
xHNFxKh,9189649254851611674,wekXkz
UdXbWt,5798071894220585051,aXTCN
dBAFajDETW,51108358544336410,SDiCm
PegUDfxmZ,-7177969302357461608,WCFqG
owMUJxJ,-4796903940677604927,PDGTsz
qHWuT,-240563331985925829,zbIHrou
IOQQ,-2443470137410847585,TOesIwEKU
YuGeUFxe,-1223651046437030469,QAnD
vNdC,6275676595378184969,RBWSl
oeWZGZo,-6524524667812109064,lmkKadQFn
OrYpmvsqQP,-6389873039790815824,NWqHR
RppUmOab,-8190312460001678874,EDaTfmGoHr
peESRSem,-3405901974520244188,VcMVZrQoy
XjtQ,-2780147053298895861,KSdKFup
ZkIU,-3116685076413995044,AQRLuD
tLJliB,-3728262480552624055,OhOO
OkinzQq,-2719293460958223478,YMIUYda
xOjmyS,485149365699621237,qCHk
wofOk,-821528230421461524,YCRlhqtcK
QJsd,5910143743306614790,HBAM
juccmti,-4425947130777827620,FCxmChg
ZfkLW,8061618111940372973,AlGl
oaWXbAOC,-1274978583030864998,aUNdfoufp
ULQKQyC,8241845601289734467,zAcmeGA
llQcU,8486017168709435435,EVGOXHXa
ptqAfGjC,-6212884822357925332,rhCaq
kXCewbzx,-3784023400544820619,vdhMzNeUC
ChJAsfJ,-1584521018535907013,cGNlFJarnN

```
</details>

### ダミーデータの生成とデータベースへの挿入
gofakeitを使用してダミーデータを生成し、それをデータベースに挿入することができます。たとえば、SQLデータベースを使用している場合は、データの挿入文を生成し、データベースクエリを実行してデータを挿入することができます。

```go:ダミーデータの生成とデータベースへの挿入
package main

import (
	"database/sql"
	"log"

	"github.com/brianvoe/gofakeit/v6"
	_ "github.com/go-sql-driver/mysql"
)

type Person struct {
	Name    string
	Age     int
	Country string
}

func main() {
	// データベースへの接続
	db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/mydatabase")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// ダミーデータの生成と挿入
	for i := 0; i < 100; i++ {
		var person Person
		gofakeit.Generate(&person)

		// データベースに挿入するクエリの作成と実行
		_, err := db.Exec("INSERT INTO people (name, age, country) VALUES (?, ?, ?)",
			person.Name, person.Age, person.Country)
		if err != nil {
			log.Fatal(err)
		}
	}
}

```

## モックデータの生成
gofakeitを使用して、特定のデータ構造や形式に基づいたモックデータを生成することができます。たとえば、特定のJSONスキーマに基づいてランダムなJSONデータを生成する場合などです。

```go:モックデータの生成
package main

import (
	"encoding/json"
	"fmt"
	"log"

	"github.com/brianvoe/gofakeit/v6"
)

type Product struct {
	ID       string  `json:"id"`
	Name     string  `json:"name"`
	Price    float64 `json:"price"`
	Quantity int     `json:"quantity"`
}

func main() {
	// モックデータの生成
	var products []Product
	for i := 0; i < 10; i++ {
		product := Product{
			ID:       gofakeit.UUID(),
			Name:     gofakeit.RandomString([]string{"Apple", "Banana", "Orange", "Grapes"}),
			Price:    gofakeit.Float64Range(10, 100),
			Quantity: gofakeit.Number(1, 100),
		}
		products = append(products, product)
	}

	// モックデータの表示
	for _, product := range products {
		fmt.Printf("ID: %s\n", product.ID)
		fmt.Printf("Name: %s\n", product.Name)
		fmt.Printf("Price: %.2f\n", product.Price)
		fmt.Printf("Quantity: %d\n\n", product.Quantity)
	}

	// モックデータのJSON出力
	jsonData, err := json.MarshalIndent(products, "", "  ")
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("JSONデータ:")
	fmt.Println(string(jsonData))
}

```

[PlayGroundで実行確認](https://go.dev/play/p/0psyNdIv-x4)

この例では、`Product`構造体を使用してモックの商品データを生成しています。10個の商品データを生成し、それぞれにランダムなID、商品名、価格、数量を割り当てています。

生成されたモックデータは、ループを使用して表示されます。また、`json.MarshalIndent()`を使用してモックデータをJSON形式で出力しています。

### その他にも
- APIのテストデータの生成
gofakeitを使用して、APIのテストデータを生成することができます。たとえば、APIのリクエストパラメータやレスポンスの形式に合わせてデータを生成し、テストシナリオを実行してAPIの振る舞いをテストすることができます。
- データベースのシーディング（seed)
gofakeitを使用してデータベースのテーブルを初期化する際に便利です。例えば、ランダムなユーザーや製品のデータを生成してデータベースに挿入することができます。
-  テストデータの生成
ユニットテストや統合テストのために、ランダムなテストデータを生成する必要がある場合にgoFakeitを使用できます。例えば、ユーザーのモックデータやAPIのリクエストパラメータのテストデータを生成することができます。

# まとめ
このようにただダミーデータを作るだけのように感じますが、応用したりすることで色々なことが自動化できるようになるので本当に便利にプログラミングが出来る様になります。皆さんもどんどん使用してみてください！！