Medium 清新閱讀版:連結
過去兩週,我們演練了許多測試方式,不過不知道大家有沒有發現,我們測試的大多是「正向」情況,「反向」的情況反而沒有測試到,也就是例外情況。
例外情況也可以測試嗎?當然可以!
本篇文章會為大家介紹如何「成功地測試失敗」。
$this->expectException()
expectException(string $exception):
$this->expectExceptionMessage()
expectExceptionMessage(string $message)
$this->expectExceptionMessageMatches()
expectExceptionMessageMatches(string $regularExpression)
$this->expectExceptionCode()
expectExceptionCode($code)
app/Services/TestService.php
<?php
namespace App\Services;
use Exception;
class TestService
{
    /**
     * @throws Exception
     */
    public function calculateBmi(float $height, float $weight): float
    {
        if ($weight <= 0 || $height <= 0) {
            throw new Exception('Invalid input!', 1);
        }
        return $weight / ($height * $height);
    }
}
這邊借用了前幾天的計算BMI程式碼當範例,並加入了「當輸入不符預期時,將拋出例外」的這個行為。
tests/Feature/ExceptionTest.php
<?php
namespace Tests\Feature;
use App\Services\TestService;
use Exception;
use Tests\TestCase;
class ExceptionTest extends TestCase
{
    /**
     * @return void
     */
    public function testCanThrowExceptionWhenInvaliHeight()
    {
        $service = app(TestService::class);
        $this->expectException(Exception::class);
        $service->calculateBmi(0.0, 1.0);
    }
    /**
     * @return void
     */
    public function testCanThrowExceptionWhenInvaliWeight()
    {
        $service = app(TestService::class);
        $this->expectException(Exception::class);
        $service->calculateBmi(1.0, 0.0);
    }
    /**
     * @return void
     */
    public function testCanThrowExceptionWithMessageWhenInvaliData()
    {
        $service = app(TestService::class);
        $this->expectExceptionMessage('Invalid');
        $service->calculateBmi(0.0, 1.0);
    }
    /**
     * @return void
     */
    public function testCanThrowExceptionWithMessageRegexMatcchWhenInvaliData()
    {
        $service = app(TestService::class);
        $this->expectExceptionMessageMatches('/Invalid/');
        $service->calculateBmi(0.0, 1.0);
    }
    /**
     * @return void
     */
    public function testCanThrowExceptionWithCodeWhenInvaliData()
    {
        $service = app(TestService::class);
        $this->expectExceptionCode(1);
        $service->calculateBmi(0.0, 1.0);
    }
}
以上我們共撰寫了5個測試案例。
第1個測試案例 testCanThrowExceptionWhenInvaliHeight(),驗證了當輸入不合理的身高值時,目標函數是否會拋出例外。
第2個測試案例 testCanThrowExceptionWhenInvaliWeight(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外。
第3個測試案例 testCanThrowExceptionWithMessageWhenInvaliData(),驗證了當輸入不合理的身高值時,目標函數是否會拋出例外,且包含指定的例外訊息。
第4個測試案例 testCanThrowExceptionWithMessageRegexMatcchWhenInvaliData(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外,且其例外訊息符合指定的Regex形式。
第5個測試案例 testCanThrowExceptionWithCodeWhenInvaliData(),驗證了當輸入不合理的體重值時,目標函數是否會拋出例外,且例外代碼與預期相符。
以上就是今天的演練,希望對大家了解例外測試有所幫助。
明天來看看 PHPUnit 的 Annotation 吧!