[新手開發記錄] 驗證資料的測試

Affren發表於2020-05-29

我準備開發一個名校公開課的漢化資料下載和討論版,功能就是站長髮布資訊和資料下載連結,使用者可以在下面討論,並且可以生成各種平臺的分享方式分享出去。這一系列文章就記錄這一過程。當然博文功能也是必不可少的。

新建一個測試

我們已經測試了資料完備的情況下,可以新建一個 course。
但是資料如果不完備,我們應該要能夠驗證並報錯,所以我們新建一個測試,如下:

/** @test */
    public function a_course_reauires_a_title()
    {
        $this->post('/courses', [])->assertSessionHasErrors('title');
    }

解釋起來就是,注意看第二個引數是 [],一個空陣列,也就是說沒有 title 可以看到,所以我們就期待看到一個關於 title 的異常,也就是這段程式碼的含義 assertSessionHasErrors('title')
那麼這時候自然會報錯,因為我們並沒有對 title 進行資料驗證,所以我們進入 CoursesControllerstore() 方法,將驗證寫出來,順便把 description 也寫了,description 的測試邏輯是一樣的,所以下面我只記錄一下 title 的驗證過程:

request()->validate(['title' => 'required', 'description' =>'required']);

這時候測試就通過了。

如果對於資料驗證有些不熟悉,參考這個視訊回顧一下:
【中文語音】(25)表單驗證基礎 - Laracasts - Laravel 6 From Scratch

資料工廠

雖然上面的測試是可以通過測試的,但是存在一個問題,因為我傳入了空陣列,所以資料欄位多的話可能會由於其他欄位的錯誤而引發不可預測的異常,從而影響這個單獨對 title 的測試,所以最理想的狀態是傳入所有其他欄位正確的資訊,僅僅將 title 賦值為空字串,那麼就可以保證測試僅僅是針對 title 的了。
我們怎麼做呢?
我們通過 Factory 來生成資料,參考:【中文語音】(30)理解外來鍵和資料庫工廠 - Laracasts - Laravel 6 From Scratch
我們新建一個 CourseFactory,所使用的模型是 Course

php artisan make:factory CourseFactory --model="Course"

檔案生成如下:

<?php

/** @var \Illuminate\Database\Eloquent\Factory $factory */

use App\Course;
use Faker\Generator as Faker;

$factory->define(Course::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'description' => $faker->paragraph
    ];
});

其中的 'title' => $faker->sentence,'description' => $faker->paragraph 就是我們自己寫進去的資料生成方式。
接下來我們就可以通過 factory() 幫助函式來生成我們要的資料了,有幾個不同的方法:

$attributes = factory('App\Course')->make();//返回一個物件,但不儲存到資料庫
$attributes = factory('App\Course')->raw();//返回一個陣列
$attributes = factory('App\Course')->create();//直接建立插入資料庫並返回一個物件

我們測試種需要傳入陣列,所以選擇第二個函式 raw()
另外,這三個方法都可以傳入一個陣列作為引數,可以對生成的資料中的某些欄位進行覆蓋,由於我們需要測試 title,要令其為空字串,所以最終我們新增的完整程式碼如下:

/** @test */
    public function a_course_reauires_a_title()
    {
        $attributes = factory('App\Course')->raw(['title' => '']);

        $this->post('/courses', $attributes)->assertSessionHasErrors('title');
    }

通過工廠生成一組新的資料,同時覆蓋其原本生成的 title 值,改為空字串,然後傳入我們的從測試程式碼,最後判斷是否會收到一個關於 title 的異常,結果再次測試通過。
description 的測試類似,不再贅述。

最後

這就是整個的一個基本流程演示,剛開始編寫的時候確實比較慢,但是隨著你的測試越寫越多,後面的開發會越來越快,並且良好的測試體系讓你重構的時候充滿信心,一旦你有任何的錯誤,你一執行測試就會立即知道。
關於重構,可以再參考一些案例,自己以後寫的時候,也可以更有把握:

  1. 【中文語音】(26)控制器重構技巧-1-路由模型繫結 - Laracasts - Laravel 6 From Scratch
  2. 【中文語音】(27) 控制器重構技巧-2-減少重複 - Laracasts - Laravel 6 From Scratch
  3. 【中文語音】(28)控制器重構技巧-3-考慮給路由命名 - Laracasts - Laravel 6 From Scratch
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章