iT邦幫忙

第 11 屆 iT 邦幫忙鐵人賽

DAY 21
0
Modern Web

Laravel 6.0 初體驗!怎麼用最新的 laravel 架網站!系列 第 21

[Day 21] 和資料庫相關的測試!怎麼測試資料庫的存取

寫了資料庫的新增,修改,刪除功能後。我們當然希望能保證,後續的修改不會將我們已經寫好的功能改壞。

這時候,我們就需要針對資料庫的測試囉!

測試存取資料庫

有關資料庫的存取,最好的測試方式,還是實際建立一個和真實環境系統差不多的資料庫,來進行測試。

幸運的是,該怎麼做比較好,這一段 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() 斷言資料庫裡面應該要有一筆 contentLaravel 6.0 tutorial day 21 的資料。

如果通過測試的話,那我們就知道 store() 的行為符合我們的預期,通過測試囉!

如果有任何疑惑的地方,可以在 testing 裡面再找看看,應該可以確實找到 contentLaravel 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',
    ]);
}

順利的話,我們應該可以通過測試,並且可以在資料庫裡面找到 contentLaravel 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',
    ]);
}

順利的話,我們應該可以通過測試,並且可以在資料庫裡面找到 contentLaravel 6.0 tutorial day 21-4deleted_at 有時間戳記的資料。

這樣,我們就成功的測試 destroy() 函式囉。


小小總結一下今天我們學到了什麼。

今天我們學到了怎麼利用 laradock 建立測試資料庫,怎麼快速的安裝測試資料庫架構和測試資料,以及撰寫了針對資料三個動作的測試!

希望各位覺得有學到東西,我們明天見!


上一篇
[Day 20] 刪除文章但是不刪除資料!聊 Soft Delete
下一篇
[Day 22] 實作用戶權限!談 Laravel Policy
系列文
Laravel 6.0 初體驗!怎麼用最新的 laravel 架網站!30

1 則留言

0
Lucas
iT邦新手 5 級 ‧ 2019-09-23 23:02:07

嗯...好像少了一些標點符號/images/emoticon/emoticon19.gif

現在有點太累了,可能有點不通順XD 不好意思

我要留言

立即登入留言