PHPでテストデータを Faktory + Faker で良い感じに生成する。


はじめに
--

テストデータを生成する方法を探していて、最終的に [Faktory](https://github.com/adamwathan/faktory) + [Faker](https://github.com/fzaninotto/Faker#fakerproviderbase) の2つのライブラリを使用して作成することにしてみました。今回はその手順を纏めてみました。

使用するライブラリについて
--

### Faktory

テストオブジェクト作成用のライブラリです。Rails 等だと FactoryGirl と呼ばれるものがあるかと思いますが、Faktory はそれに非常に近い作りになっていると README.md を確認している中で個人的に感じました。FactoryGirl-PHP というモロにそれな奴もあったのですが、Faktory のほうが README.md が丁寧に書いてあること、最終 commit が近いことから、Star の数は劣るものの Faktory を選択することにしました。

### Faker

テストの偽造データ作成用のライブラリです。英語のデータだけでなく日本語のデータ作成も簡単におこなえることが公式ドキュメントの Localization から解ったこと、こちらも README.md が丁寧に書かれてあることから使用してみることにしました。ちなみに Star の数も滅茶苦茶多いです！凄い！！
	
準備
--

どちらのライブラリも composer でサクッとインストールが行えます。簡単で良いです。

```sh
# faker のインストール
$ composer require fzaninotto/faker

Using version ^1.5 for fzaninotto/faker
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing fzaninotto/faker (v1.5.0)
    Downloading: 100%

Writing lock file
Generating autoload files
```

```sh
# faktory のインストール
$ composer require adamwathan/faktory

Using version ^0.4.1 for adamwathan/faktory
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
  - Installing adamwathan/faktory (v0.4.1)
    Downloading: 100%

Writing lock file
Generating autoload files
```

Faktory でテストオブジェクトを作ってみる
--

まずは、Faktory 単体を使用してテストオブジェクトを作成してみたいと思います。
下記のコードを person.php というファイルを作成して貼り付けます。

```php
require './vendor/autoload.php';

use AdamWathan\Faktory\Faktory;

class Person {}

$faktory = new Faktory;
$faktory->define('Person', function ($f) {
  $f->name = 'kenya yamaguchi';
});

$person = $faktory->build('Person');
var_dump($person);
```

実行してみましょう。
下記のように正しくテストオブジェクトが生成されていることが解ると思います。

```sh
$ php person.php

object(Person)#7 (1) {
  ["name"]=>
  string(15) "kenya yamaguchi"
}
```

Faker を組み合わせてみる
--

それでは、最後に Faker と組み合わせてタイトルの通り良い感じにテストデータを生成したいと思います。先程のperson.phpを下記の用に修正しましょう。

```php
<?php
require './vendor/autoload.php';

use AdamWathan\Faktory\Faktory;

class Person {}

$faktory = new Faktory;
$faktory->define('Person', function ($f) {
  $f->name = '';
});

$names = [];
$faker = Faker\Factory::create('ja_JP');
for ($i = 0; $i < 10; $i++) {
  $names[] = $faker->name;
}

$persons = $faktory->buildMany('Person', 10, [
  'name' => $names,
]);

var_dump($persons);
```

実行してみましょう。
下記のように正しくテストオブジェクトが偽造データ入りで良い感じに生成されていることが解ると思います。

```sh
$ php person.php

array(10) {
  [0]=>
  object(Person)#26 (1) {
    ["name"]=>
    string(13) "伊藤 康弘"
  }
  [1]=>
  object(Person)#27 (1) {
    ["name"]=>
    string(10) "青田 舞"
  }
  [2]=>
  object(Person)#28 (1) {
    ["name"]=>
    string(13) "三宅 春香"
  }
  [3]=>
  object(Person)#29 (1) {
    ["name"]=>
    string(13) "宇野 直子"
  }
  [4]=>
  object(Person)#30 (1) {
    ["name"]=>
    string(13) "大垣 翔太"
  }
  [5]=>
  object(Person)#31 (1) {
    ["name"]=>
    string(10) "坂本 淳"
  }
  [6]=>
  object(Person)#32 (1) {
    ["name"]=>
    string(10) "斉藤 零"
  }
  [7]=>
  object(Person)#33 (1) {
    ["name"]=>
    string(16) "三宅 さゆり"
  }
  [8]=>
  object(Person)#34 (1) {
    ["name"]=>
    string(10) "斉藤 学"
  }
  [9]=>
  object(Person)#35 (1) {
    ["name"]=>
    string(13) "吉田 春香"
  }
}
```

最後に
--

Faktory も Faker も触り始めたばかりなので、未だまだ自身が知らないことが多いので、引き続き触っていきたいと思います。また、「こんなことも出来るよ」や「このライブラリを使用するのが標準的だよ」というものがあれば教えて頂けると幸いです。 :bow: