自动生成测试数据
Back to series
开发HTTP API之前,一个无聊却又重要的事情,就是为测试准备好数据。这样,我们才可以方便的验证API的各种行为。好在,Laravel在创建表,生成记录结果,填充表到删除记录这些环节都提供了方便的自动化功能。
因此,在上手开发API之前,我们先来了解如何基于Laravel准备测试数据。在下面的例子中,所有的操作将基于Laravel Homestead。
创建数据库
新创建一个Laravel 5.3项目,例如:boxue_lite。并且,在Homestead.yaml中添加下面的配置:
folders:
- map: /Users/puretears/projects/boxue_lite
to: /var/www/boxue_lite/current
sites:
- map: api.boxue.io
to: /var/www/boxue_lite/current/public
databases:
- boxue_lite
之后,重启Homestead,我们就新建了一个boxue_lite的测试环境,并且在Homestead中创建了叫做boxue_lite的数据库。
最后,在项目根目录中的.env文件中,把DB_DATABASE改成boxue_lite:
DB_DATABASE=boxue_lite
创建表
创建好数据库之后,在项目的根目录,执行:
php artisan make:migration CreateEpisodeTable —create=”episodes”
这样,Laravel就会在database/migrations目录,创建一个名为时间戳_CreateEpisodeTable的migration文件,在其中的up方法里,我们可以看到表名已经设置成了我们在—create参数中传递的episodes:
public function up()
{
Schema::create('episodes', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
});
}
我们将使用这个文件,来定义episodes表的Schema。为了简单起见,我们只是添加两个column:
title表示视频的标题;
description表示视频的简介;
把up中的Schema改成这样:
Schema::create('episodes', function (Blueprint $table) {
$table->increments('id');
$table->string('title', 64);
$table->text('description');
$table->timestamps();
});
其中:
string会被转换成SQL中的VARCHAR,第二个参数用于限定字符串的长度;
text则会被转换成SQL中的TEXT。完成后,在项目根目录,执行:php artisan migrate,Laravel就会根据Schema中指定的规格为我们自动创建episodes表了;
创建Model
接下来,为了在PHP中方便的访问episodes表中的记录,我们需要给它创建一个model。简单来说,一个Moel就是数据库中一个表的PHP类定义。
在项目的根目录,执行:php artisan make:model Episode。这样,Laravel就会自动在app/目录创建一个名为Episode.php的文件:
namespace App;
use Illuminate\Database\Eloquent\Model;
class Episode extends Model
{
//
}
Laravel怎么知道Episode对应的就是episodes表呢?
在Laravel里,有一些约定俗成的内容。例如,所有的model都是大写字母单数形式的单词,它对应的,就是数据库中,以小写字母开头的对应复数单词。因此,Episode model对应的就是episodes表。
当然,如果你不习惯上面约定俗成的内容,也可以通过重定义Model中的属性来明确它,例如:
class Episode extends Model
{
//
protected $table = 'episodes';
}
这样,就明确指定了Episode对应的表的名字。不过建议你还是尊从Laravel中约定俗成的内容。
最后,我们在Episode中,通过$fillable属性指定哪些字段是可以批量赋值的。它是一个数组,存放可以批量赋值的列名。因为稍后,我们要给episodes表批量中添加一些测试数据,我们指定title和description就可以了:
class Episode extends Model
{
//
protected $fillable = [ 'title', 'description' ];
}
Factory & Seed
表和Model都创建好之后,我们就可以创建数据填充规则并执行填充动作了。在Laravel里,它们分别由ModelFactory和Seeder这两个类来完成。
首先,在database/factories目录,创建一个EpisodeFactory.php文件,然后添加下面的代码:
$factory->define(App\Episode::class,
function(Faker\Generator $faker) {
return [
'title' => $faker->sentence(4),
'description' => $faker->paragraph(3)
];
});
其中Faker是一个被Laravel集成进来的非常方便的生成各种不同类型测试数据的PHP library。大家可以在它的Github主页,了解更多详细的用法。在我们的例子里,只是随机生成了一个4个单词的句子,以及3个段落的描述。
其次,有了记录的生成规则之后,就可以通过Seeder来创建记录了。在项目根目录执行:php artisan make:seeder EpisodeSeeder。Laravel就会在database/seeds目录里,创建一个EpisodeSeeder.php文件,其中包含了一个叫做EpisodeSeeder class。在其中的run方法里,添加下面的代码:
/**
+ Run the database seeds.
*
+ @return void
*/
public function run()
{
//
factory(App\Episode::class, 20)->create();
}
这样,我们就可以自动生成20条episodes表的随机记录,并写入episodes表了。
最后,在Laravel默认的DatabaseSeeder.php的run方法里,添加调用EpisodeSeeder的代码:
// In DatabaseSeeder.php
public function run()
{
Episode::truncate();
$this->call(EpisodeSeeder::class);
}
完成后,在项目根目录执行:php artisan db:seed,就完成episodes表的自动填充了。Laravel会给我们类似下面的提示:
vagrant@homestead:/var/www/boxue_lite/current$ php artisan db:seed
Seeded: EpisodeSeeder
What’s next?
准备好测试数据之后,我们就可以着手第一个HTTP API了。在下个例子中,我们向大家介绍如何把一个Eloquent对象的查询结果,通过JSON返回给客户端。
来自泊学网