一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

4. 使用Model Factories快速生成測(cè)試數(shù)據(jù)

 鳥哥軟件 2017-05-03

我們?cè)陂_發(fā)的時(shí)候經(jīng)常會(huì)需要修改已經(jīng)寫好的創(chuàng)建表的migration文件,但是又不想在開發(fā)時(shí)就寫太多的修改或者添加表字段的migration文件,導(dǎo)致migration文件過(guò)多,而如果直接修改了已經(jīng)創(chuàng)建好的migration文件,那就必須要migrate:refresh了,但是表中的測(cè)試數(shù)據(jù)重新添加又是件麻煩的事,這時(shí)候我們就可以使用laravel的數(shù)據(jù)填充功能Seeder, 在討論這個(gè)Seeder之前,我們先來(lái)看下如何批量生成測(cè)試數(shù)據(jù)。

laravel框架默認(rèn)引入了fzaninotto/Faker包,這個(gè)包能讓我們快速的生成一些測(cè)試數(shù)據(jù)。包的開發(fā)思路基于Perl的Data::Faker和ruby的faker。這個(gè)包的具體使用方式在這里https://github.com/fzaninotto/Faker,我們來(lái)看下在Laravel中如何使用它.

我們?nèi)ヅ芤粋€(gè)Laravel 5.3的框架,并且建立好數(shù)據(jù)庫(kù),并執(zhí)行掉php artisan migrate命令。這里自己做,大家應(yīng)該是可以閉著眼睛做好這些了。

所有的model factories我們都會(huì)放在database/factories/ModelFactory.php中,我們打開它:

<?php

/*
| Model Factories 
|
| Here you may define all of your model factories. Model factories give
| you a convenient way to create models for testing and seeding your
| database. Just tell the factory how a default model should look.
| 你可以在這里定義你所有的模型工廠,使用模型工廠可以讓我們?cè)趩卧獪y(cè)試的時(shí)候很方便的使用生成
| 的測(cè)試數(shù)據(jù),同時(shí)也可以快速的將測(cè)試數(shù)據(jù)保存到我們的數(shù)據(jù)庫(kù)中。
*/

$factory->define(App\User::class, function (Faker\Generator $faker) {
    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->email,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

默認(rèn)的已經(jīng)有了一個(gè)為User模型生成測(cè)試數(shù)據(jù)的方法,這里的$faker->name,$faker->unique()->email都是fzaninotto/Faker包提供,上面已經(jīng)給了它的github地址,大家用的時(shí)候自己去查找下就行。

怎么使用它呢? 我們打開php artisan tinker, 執(zhí)行

 factory(App\User::class)->make();

這句話的意思是,我們會(huì)生成一個(gè)User對(duì)象,但是我們會(huì)使用模型工廠全局幫助函數(shù)factory()來(lái)生成它,生成的時(shí)候就給對(duì)象的所有屬性賦值。結(jié)果如下:

Psy Shell v0.8.0 (PHP 7.0.12 — cli) by Justin Hileman
>>> factory(App\User::class)->make();
=> App\User {#692
     name: "Candace Bins",
     email: "morar.ethan@gmail.com",
   }
>>> factory(App\User::class)->make();
=> App\User {#698
     name: "Prof. Alf Graham MD",
     email: "mpagac@yahoo.com",
   }

每調(diào)用一次都會(huì)生成一個(gè)具有不同屬性值的對(duì)象,那如果我們要同時(shí)生成多個(gè)這樣的對(duì)象呢?比如我們要生成500個(gè)User對(duì)象,我們只要傳入第2個(gè)參數(shù)即可,如下:

factory(App\User::class, 500)->make();

通常我們會(huì)需要將這些生成的數(shù)據(jù)保存到數(shù)據(jù)庫(kù),那使用create()即可

factory(App\User::class, 2)->create();

不過(guò)我們一般就不跑到tinker中去生成這樣測(cè)試數(shù)據(jù)了,我們將這條語(yǔ)句些到seeds/DatabaseSeeder.phprun方法中:

    public function run()
    {
        // 清空users表中已經(jīng)存在的數(shù)據(jù)
        User::truncate();

        factory(User::class, 2)->create();
    }

然后執(zhí)行:

php artisan db:seed

就會(huì)調(diào)用上面這個(gè)run()方法,執(zhí)行當(dāng)中的語(yǔ)句了。

不過(guò)在正式開發(fā)的時(shí)候,$faker數(shù)據(jù)要依據(jù)你的具體情況來(lái)用了,比如我們會(huì)需要一些真實(shí)的數(shù)據(jù),比如說(shuō)一些字典表,那必須是正確的數(shù)據(jù),那就會(huì)手動(dòng)指定了,所以通常我們對(duì)應(yīng)每個(gè)模型都會(huì)去寫一個(gè)Seeder類,然后在DatabaseSeeder.php中去調(diào)用它們,在具體的Seeder類中去調(diào)用模型工廠,這樣代碼會(huì)方便管理很多,因?yàn)楝F(xiàn)在還沒(méi)有講到Seeder類,所以我們現(xiàn)在知道怎么用模型工廠就可以了。

對(duì)于模型工廠的數(shù)據(jù),我們可能更多的還是用在測(cè)試中的(測(cè)試以后最后再詳說(shuō)),我們看下測(cè)試中怎么用:

我們?nèi)ソ⒁粋€(gè)posts表,migration文件如下:

    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->increments('id');
            $table->string('title');
            $table->text('body');
            $table->timestamps();
        });
    }

比如我們要測(cè)試這個(gè)流程: 當(dāng)我訪問(wèn)post的路由的時(shí)候,給我顯示數(shù)據(jù)庫(kù)中的post的標(biāo)題和內(nèi)容.

我們直接改下tests/ExampleTest.php中的代碼:

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
use App\Post;

class ExampleTest extends TestCase
{
    // 不讓測(cè)試的數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中,沒(méi)有這條語(yǔ)句,當(dāng)執(zhí)行phpunit時(shí),會(huì)
    // 在posts表中不斷的插入數(shù)據(jù),自己測(cè)試下
    use DatabaseTransactions;
    /**
     * A basic functional test example.
     *
     * @return void
     */
    public function testBasicExample()
    {
        // 通過(guò)模型工廠生成帶有測(cè)試數(shù)據(jù)屬性的$post對(duì)象
        $post = factory(Post::class)->create();

        $this->visit('posts')
             ->see($post->title);
    }
}

database/factories/ModelFactory.php中定義模型工廠:

$factory->define(App\Post::class, function (Faker\Generator $faker) {
    return [
        'title' => $faker->sentence,
        'body' => $faker->paragraph
    ];
});

編寫路由文件,laravel 5.3路由分的很細(xì),有針對(duì)api的,針對(duì)web的,還有針對(duì)命令行的,針對(duì)web的在routes/web.php中( 路由這樣改個(gè)人覺得很好,比5.2好多了)

Route::get('posts', function() {
  return view('posts')->with('posts', App\Post::all());
});

然后去弄個(gè)resources/views/posts.blade.php視圖

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>zhoujiping.com</title>
</head>
<body>
    @foreach ($posts as $post)
        <article>
            <h2>{{ $post->title }}</h2>
            <div class="body">{{ $post->body }}</div>
        </article>
    @endforeach
</body>
</html>

到命令行執(zhí)行phpunit, 是綠色的QQ20161221-0.png

我們?cè)诨仡^來(lái)說(shuō)下fzaninotto/Faker包, 默認(rèn)我們生成的測(cè)試數(shù)據(jù)都是英文的,如果你一定要想生成中文的測(cè)試數(shù)據(jù)(其實(shí)沒(méi)啥用),該怎么生成?回到database/factories/ModelFactory.php

fzaninotto/Faker源碼中我們可以看見fzaninotto/Faker的包中的關(guān)于語(yǔ)言版本相關(guān)的都放在Provider中:
1.png

而在laravel中$faker是Faker\Generator的是一個(gè)實(shí)例,在Faker\Generator中有這樣一個(gè)方法:

    public function addProvider($provider)
    {
        array_unshift($this->providers, $provider);
    }

這樣一看就明白了,將需要的語(yǔ)言文件依賴注入進(jìn)來(lái)就可以了。

那我們來(lái)改下代碼:

$factory->define(App\User::class, function (Faker\Generator $faker) {
    $faker->addProvider(new Faker\Provider\zh_CN\Person($faker));

    static $password;

    return [
        'name' => $faker->name,
        'email' => $faker->unique()->email,
        'password' => $password ?: $password = bcrypt('secret'),
        'remember_token' => str_random(10),
    ];
});

我們到tinker中跑一下:
2.png

現(xiàn)在生成的姓名就是中文的了,但是該組件對(duì)中文的支持類太少,所以你可能會(huì)在寫Seeder的時(shí)候用一部分$faker,用一部分手動(dòng)指定,或者自己寫一些數(shù)組,隨機(jī)插入也可以。

本節(jié)到這里結(jié)束。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    欧美欧美日韩综合一区| 91日韩欧美国产视频| 最新69国产精品视频| 偷拍美女洗澡免费视频| 91欧美亚洲精品在线观看| 亚洲熟妇熟女久久精品| 亚洲av日韩av高潮无打码| 最近最新中文字幕免费| 久久精品色妇熟妇丰满人妻91| 亚洲三级视频在线观看免费| 精品人妻一区二区三区在线看| 成年午夜在线免费视频| 日韩精品人妻少妇一区二区| 亚洲一区二区三区熟女少妇| 欧美自拍系列精品在线| 草草视频精品在线观看| 六月丁香六月综合缴情| 日韩精品视频香蕉视频| 精品久久久一区二区三| 亚洲午夜av一区二区| 日韩综合国产欧美一区| 久久综合亚洲精品蜜桃| 日韩人妻中文字幕精品| 大胆裸体写真一区二区| 99久久国产精品成人观看| 亚洲二区欧美一区二区| 国内胖女人做爰视频有没有| 中文字幕高清免费日韩视频| 久久91精品国产亚洲| 国产不卡一区二区四区| 色鬼综合久久鬼色88| 欧美不卡午夜中文字幕| 日本成人中文字幕一区| 中文久久乱码一区二区| 欧美有码黄片免费在线视频| 欧美国产日本免费不卡| 亚洲精品偷拍视频免费观看| 久久精品久久久精品久久| 久久热麻豆国产精品视频| 国产免费观看一区二区| 久久99这里只精品热在线|