資料庫測試
public function testDatabase(){ // Make call to application... $this->assertDatabaseHas('users', [ 'email' => 'sally@example.com' ]); }您也可以使用
assertDatabaseMissing 幫助程式斷言資料庫中不存在資料。
assertDatabaseHas 方法和其他類似的幫助程式是為了方便起見。您可以自由使用任何 PHPUnit 的內建斷言方法來補充您的測試。
make:factory Artisan command 指令可以建立一個模型工廠:
php artisan make:factory PostFactory新產生的工廠位置在
database/factories 目錄下。
--model 選項可用來指示工廠建立的模型的名稱。此選項將使用給定模型預先填充生成的工廠檔案:
php artisan make:factory PostFactory --model=Post#每次測試後重置資料庫在每次測試後重置資料庫通常很有用,這樣前一次測試的資料不會幹擾後續測試。
RefreshDatabase 特徵採用最最佳化的方法來遷移測試資料庫,這取決於您使用的是記憶體資料庫還是傳統資料庫。在測試類別上使用特徵,一切都將為您處理:
<?php namespace Tests\Feature; use Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; use Illuminate\Foundation\Testing\WithoutMiddleware; class ExampleTest extends TestCase{ use RefreshDatabase; /** * 一个基本功能测试示例 * * @return void */ public function testBasicExample() { $response = $this->get('/'); // ... } }#建立模型工廠測試時,您可能需要執行測試之前將幾筆記錄插入資料庫。在建立此測試資料時, Laravel 不是手動指定每列的值,而是允許您使用模型工廠為每個 Eloquent 模型 定義一組預設屬性。開始測試前,請先查看應用程式中的
database / factories / UserFactory.php 檔案。開箱即用,此檔案包含一個工廠定義:
use Illuminate\Support\Str; use Faker\Generator as Faker; $factory->define(App\User::class, function (Faker $faker) { return [ 'name' => $faker->name, 'email' => $faker->unique()->safeEmail, 'email_verified_at' => now(), 'password' => 'y$TKh8H1.PfQx37YgCzwiKb.KjNyWgaHb9cbcoQgdIVFlYg7B77UdFm', // secret 'remember_token' => Str::random(10), ]; });
在用作工廠定義的 Closure 中,您可以傳回模型上所有屬性的預設測試值。 Closure 將會收到 Faker PHP 函式庫的實例,它允許您方便地產生各種隨機資料以進行測試。
您也可以為每個模型建立其他工廠文件,以便更好地進行組織。例如,您可以在 database / factories
目錄中建立 UserFactory.php
和 CommentFactory.php
檔案。 factories
目錄中的所有檔案將由 Laravel 自動載入。
您可以透過在
config / app.php
設定檔中新增faker_locale
選項來設定 Faker 的語言環境。
工廠狀態
States 可讓您定義可以任意組合套用於模型工廠的離散修改。例如,您的 User
模型可能具有 deinquent
狀態,可以修改其預設屬性值之一。您可以使用 state
方法定義狀態轉換。對於簡單狀態,您可以傳遞一組屬性修改:
$factory->state(App\User::class, 'delinquent', [ 'account_status' => 'delinquent', ]);
如果你的狀態需要計算或$ faker
實例,你可以使用Closure 來計算狀態的屬性修改:
$factory->state(App\User::class, 'address', function ($faker) { return [ 'address' => $faker->address, ]; });
工廠回呼
使用afterMaking
和afterCreating
方法註冊工廠回呼,並允許您在創建或創建模型後執行其他任務。例如,您可以使用回呼將其他模型與建立的模型相關聯:
$factory->afterMaking(App\User::class, function ($user, $faker) { // ... }); $factory->afterCreating(App\User::class, function ($user, $faker) { $user->accounts()->save(factory(App\Account::class)->make()); });
您也可以為工廠狀態定義回呼:
$factory->afterMakingState(App\User::class, 'delinquent', function ($user, $faker) { // ... }); $factory->afterCreatingState(App\User::class, 'delinquent', function ($user, $faker) { // ... });
使用模型工廠
建立模型
模型工廠定義後,就可以在測試或種子檔案中使用全域factory
函數來產生模型實例。那麼,讓我們來看一些創建模型的範例。首先,我們將使用make
方法建立模型,但不將它們儲存到資料庫中:
public function testDatabase(){ $user = factory(App\User::class)->make(); //在测试中使用模型... }
您也可以建立許多模型的集合或建立給定類型的模型:
//创建三个 App\User 实例... $users = factory(App\User::class, 3)->make();
套用狀態
您也可以將任何states 套用到模型。如果要將多個狀態轉換套用到模型,則應指定要套用的每個狀態的名稱:
$users = factory(App\User::class, 5)->states('delinquent')->make(); $users = factory(App\User::class, 5)->states('premium', 'delinquent')->make();
覆寫屬性
如果要覆寫模型的某些預設值,可以將一組值傳遞給make
方法。只有指定的值才會被替換,而其餘值仍然設定為工廠指定的預設值:
$user = factory(App\User::class)->make([ 'name' => 'Abigail', ]);
#持久化模型
create
方法不僅建立了模型實例,還使用Eloquent 的save
方法將它們儲存到資料庫中:
public function testDatabase(){ // 创建单个 App\User 实例... $user = factory(App\User::class)->create(); // 创建3个 App\User 实例.. $users = factory(App\User::class, 3)->create(); // 在测试中使用模型... }
您可以透過將陣列傳遞給create
方法來覆寫模型上的屬性:
$user = factory(App\User::class)->create([ 'name' => 'Abigail', ]);#
關聯
在這個範例中,我們將附加一些建立模型的關係。當使用create
方法建立多個模型時,會傳回一個Eloquent 集合實例,這樣就可以在集合上使用each 等便利方法:
$users = factory(App\User::class, 3) ->create() ->each(function ($user) { $user->posts()->save(factory(App\Post::class)->make()); });
關聯& 屬性閉包
您也可以使用工廠定義中的Closure 屬性將關係附加到模型。例如,如果您想在建立Post
時建立一個新的User
實例,您可以執行下列操作:
$factory->define(App\Post::class, function ($faker) { return [ 'title' => $faker->title, 'content' => $faker->paragraph, 'user_id' => function () { return factory(App\User::class)->create()->id; } ]; });
這些閉包接收一個包含工廠屬性的陣列:
$factory->define(App\Post::class, function ($faker) { return [ 'title' => $faker->title, 'content' => $faker->paragraph, 'user_id' => function () { return factory(App\User::class)->create()->id; }, 'user_type' => function (array $post) { return App\User::find($post['user_id'])->type; } ]; });
可用的斷言方法
Laravel 為PHPUnit 測試提供了多個資料庫斷言方法:
方法 | 描述 |
---|---|
#$this->assertDatabaseHas( $table, array $data); | 斷言資料庫表中包含給定的資料。 |
$this->assertDatabaseMissing($table, array $data); | 斷言資料庫表中不包含給定的資料。 |
$this->assertSoftDeleted($table, array $data); | 斷言資料庫中的指定記錄已軟刪除。 |