顯示具有 Laravel 標籤的文章。 顯示所有文章
顯示具有 Laravel 標籤的文章。 顯示所有文章

2019/06/28

注意 PHPUnit 的 fixture 行為

理論上,各個 test case 不應該互相影響,所以 PHPUnit 設計的 fixtures 像是 setUp() 和 tearDown() 都會在各個 test case 前後執行。

簡單做個測試:
<?php

use PHPUnit\Framework\TestCase;

class LibTest extends TestCase
{
    public function setUp(): void
    {
        $this->data = null;
    }

    public function tearDown(): void
    {
        $this->data = null;
    }

    public function testOne()
    {
        $this->data = 123;
        $this->assertEquals(123, $this->data);

        return $this->data;
    }

    /**
     * @depends testOne
     */
    public function testTwo($data)
    {
        $this->assertEquals(123, $this->data);
    }
}

// -----

PHPUnit 8.2.3 by Sebastian Bergmann and contributors.

.F

即使在 test case 加上 @depends 標記,fixture 也會運作,所以若是要讓下一個 test case 繼續使用的測試值,都必須用 return 的方式傳值。

----

另外,Laravel 提供的 testing tools 也有相同的行為。例如:「RefreshDatabase」,在 test case 執行結束以後就會把資料清空,因此如果要對 DB 做多像檢查,就必須在同一個 test case 中建立多個 assertions (個人不喜歡這樣做),不然即使加上 @depends,DB 中的資料也會被 refresh 掉。

2019/06/27

在 Laravel unit test 手動建立 HTTP request

現在有個 controller 收到 HTTP POST data 以後才會動作,且這個 controller 為 AJAX controller,沒有 view 沒辦法用 Selenium 測試:
class TargetController extends Controller
{
    public function doSomething(Request $req)
    {
        // do something ....
    }
}

要測試的話,其實可以透過一些工具手動測試,像是 PostMan 等類似的工具。但這種測試會遇到一些問題:Middle 有檢查使用者身份、需要拿到 access token 才能進 controller 等等。這樣會讓測試多了不少不確定因素 (變因),導致測試結果不準確。

要進行測試較好的方法,就是建立一個 HTTP request 來模擬實際情況:
$req = new \lluminate\Http\Request();

$ctrl = new TargetController()
$result = $ctrl->doSomething($req);

不過可惜的是 Request 這個類別,設計原始的用意是從 $_GET、$_POST、$_FILE 等全域變數整理成物件方便 access,所以若要在 request 中加入參數,目前只能透過 replace() 來增加。例如需要新增 key/value pair,必須這樣撰寫:
$request->replace([
    'key' => 'value',
]);

至於模擬檔案上傳 .... 我還在找方法,確定了以後再來寫筆記。



Ref:

2017/03/05

Laravel 5.3 的 API routing

弄了很久才搞清楚 5.3 版的 routing 是怎麼搞的,覺得作者把事情弄的更複雜了,也少了一些彈性。

Laravel 5.3 中,routes 已經不是放在 App/Http 底下了,將設定獨立出來放在根目錄:
johnroyer@box:~/devel/laravel53$ tree routes
routes
├── api.php
├── console.php
└── web.php

有個 API 專用 routing 看了當然開心,只是怎麼樣都是不出來 api.php 這邊的設定要怎樣才能起作用。

後來找了很久才發現 Route 功能,已經在 provider 階段把 web / api 的 routing rule 寫死,所以 API 的 routing 有固定的 prefix,在網址是上必須是「http://laravel.root/api」開頭,才會吃到 api.php 的設定。該項 rule 被寫在 RouteServiceProvider 中:
    protected function mapApiRoutes()
    {
        Route::group([
            'middleware' => 'api',
            'namespace' => $this->namespace,
            'prefix' => 'api',
        ], function ($router) {
            require base_path('routes/api.php');
        });
    }


Reference: