寫了資料庫的新增,修改,刪除功能後。我們當然希望能保證,後續的修改不會將我們已經寫好的功能改壞。
這時候,我們就需要針對資料庫的測試囉!
有關資料庫的存取,最好的測試方式,還是實際建立一個和真實環境系統差不多的資料庫,來進行測試。
幸運的是,該怎麼做比較好,這一段 Laravel 一樣規劃了一套簡便的做法進行測試。我們就來試看看吧!
首先,我們建立一個 testing
資料庫,用作本機開發時測試用。
我們先在 laradock/mysql/docker-entrypoint-initdb.d/
裡面,參考 createdb.sql.example
,建立 createdb.sql
,加入
CREATE DATABASE IF NOT EXISTS `testing` COLLATE 'utf8_general_ci' ;
GRANT ALL ON `testing`.* TO 'default'@'%' ;
建立好了之後,根據 createdb.sql.example
裡面的說明,更新資料庫。
如果失敗的話,可以將 ~/.laradock/data/mysql
刪除,然後在 laradock
資料夾裡面運作
$ docker-compose up -d --build --force-recreate mysql
將整個資料庫重建。
成功的話,應該可以在資料庫主機裡面看到 testing
資料庫,那樣我們就成功囉!
還記得我們之前建立的資料庫 migration 和 seeder 嗎?在建立 testing
資料庫時,這些東西馬上就派上用場囉!
我們先建立測試專用的環境設置檔案 .env.testing
裡面全部的資料都和 .env
一樣,我們只改變
DB_DATABASE=testing
讓指定的資料庫改成 testing
然後,我們到專案資料夾,在指令列運作
$ php artisan migrate --seed --env=testing
就可以看到在 testing
資料庫裡面,資料庫架構重新建立起來,測試資料也寫好了。
這樣,測試的準備就一應俱全囉!我們準備開始撰寫測試!
跟前面的測試相同,首先我們建立新的測試檔案,PostControllerTest
$ php artisan make:test PostControllerTest
Test created successfully.
store()
然後,我們改寫 PostControllerTest.php
,加入針對 store()
的測試 testStore()
public function testStore()
{
$this->post(route('posts.store'), [
'content' => 'Laravel 6.0 tutorial day 21'
]);
$this->assertDatabaseHas('posts', [
'content' => 'Laravel 6.0 tutorial day 21',
]);
}
這邊,我們先透過 route('posts.store')
寫入資料,再利用 $this->assertDatabaseHas()
斷言資料庫裡面應該要有一筆 content
為 Laravel 6.0 tutorial day 21
的資料。
如果通過測試的話,那我們就知道 store()
的行為符合我們的預期,通過測試囉!
如果有任何疑惑的地方,可以在 testing
裡面再找看看,應該可以確實找到 content
為 Laravel 6.0 tutorial day 21
的資料。
update()
再來,我們來測試修改資料的行為。
這會需要預先在資料庫寫入一筆資料,然後針對該筆資料進行修改,之後看看修改有沒有成功地出現在資料庫裡面。
我們撰寫 testUpdate()
來測試 update()
public function testUpdate()
{
$post = new Post;
$post->content = '';
$post->subject_id = 0;
$post->save();
$this->put(route('posts.update', ['post' => $post]), [
'content' => 'Laravel 6.0 tutorial day 21-2'
]);
$this->assertDatabaseHas('posts', [
'content' => 'Laravel 6.0 tutorial day 21-2',
]);
}
順利的話,我們應該可以通過測試,並且可以在資料庫裡面找到 content
為 Laravel 6.0 tutorial day 21-2
的資料。
destroy()
最後,我們要寫一個 testDestroy()
來測試 destroy()
函式。
如果我們的 delete()
是會真的刪除資料。那麼我們可以用 assertDatabaseMissing()
來確保資料庫內確實刪除資料。寫法會類似這樣
public function testDestroy()
{
$post = new Post;
$post->content = 'Laravel 6.0 tutorial day 21-3';
$post->subject_id = 0;
$post->save();
$this->delete(route('posts.destroy', ['post' => $post]));
$this->assertDatabaseMissing('posts', [
'content' => 'Laravel 6.0 tutorial day 21-3',
]);
}
不過,如果我們執行這個測試,會發現並沒有通過。這是因為我們實作的是軟刪除,資料還留在資料庫裡面。
所以,我們要改用 assertSoftDeleted()
來確認資料成功地被軟刪除了
public function testDestroy()
{
$post = new Post;
$post->content = 'Laravel 6.0 tutorial day 21-4';
$post->subject_id = 0;
$post->save();
$this->delete(route('posts.destroy', ['post' => $post]));
$this->assertSoftDeleted('posts', [
'content' => 'Laravel 6.0 tutorial day 21-4',
]);
}
順利的話,我們應該可以通過測試,並且可以在資料庫裡面找到 content
為 Laravel 6.0 tutorial day 21-4
,deleted_at
有時間戳記的資料。
這樣,我們就成功的測試 destroy()
函式囉。
小小總結一下今天我們學到了什麼。
今天我們學到了怎麼利用 laradock 建立測試資料庫,怎麼快速的安裝測試資料庫架構和測試資料,以及撰寫了針對資料三個動作的測試!
希望各位覺得有學到東西,我們明天見!