在 [slim] 中偽造 Request 來進行你的 HTTP 測試吧

DavidNineRoc發表於2019-12-04
  • 程式碼需要做HTTP測試,Laravel中有自帶這方面的功能。現在使用slim就得自己動手豐衣足食。
  • 網上找了許多例子,關於這方便的比較少。然後就想到了檢視Laravel的原始碼
  • 看了一下,發現其實是自己偽造一個Request物件,然後執行返回結果
  • 然後自己也參考這個在slim中實現

    構建好測試檔案

  • composer.json加入以下內容自動載入,並執行composer dump-auto
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    }
  • 根目錄新建配置檔案phpunit.xml內容如下
<phpunit bootstrap="tests/bootstrap.php">
    <testsuites>
        <testsuite name="Feature">
            <directory suffix="Test.php">tests</directory>
        </testsuite>
    </testsuites>
</phpunit>
  • tests/bootstrap.php檔案內容如下
<?php
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Slim\Factory\AppFactory;

require __DIR__ . '/../vendor/autoload.php';

$app = AppFactory::create();

$app->get('/hello/{name}', function (Request $request, Response $response, array $args) {
    $name = $args['name'];
    $response->getBody()->write("Hello, $name");
    return $response;
});

$app->get('/api/v1/users', function (Request $request, Response $response) {

    $data = [['name' => 'Bob', 'age' => 40]];
    $payload = json_encode($data);

    $response->getBody()->write($payload);
    return $response
        ->withHeader('Content-Type', 'application/json');
});

// 這裡不要執行 app
// $app->run();
// 並且宣告一個函式得到 App 物件
function getApplication()
{
    global $app;

    return $app;
}
  • 建立測試檔案tests/HomeTest.php寫入一下內容
<?php

namespace Tests;
use Nyholm\Psr7\Uri;
use PHPUnit\Framework\TestCase;
use Slim\Factory\ServerRequestCreatorFactory;

class HomeTest extends TestCase
{
    public function testHello()
    {
        $name = 'Bob';

        $serverRequestCreator = ServerRequestCreatorFactory::create();
        $request = $serverRequestCreator->createServerRequestFromGlobals();

        $uri = new Uri();
        $request = $request->withUri($uri->withPath("/hello/{$name}"));

        $response = getApplication()->handle($request);
        $responseContent = (string)$response->getBody();

        $this->assertEquals($responseContent, "Hello, {$name}");
    }

    public function testJsonApi()
    {
        $serverRequestCreator = ServerRequestCreatorFactory::create();
        $request = $serverRequestCreator->createServerRequestFromGlobals();

        // 因為 Uri 和 Request 物件都是不可以修改的,所以都需要新建
        $uri = new Uri();
        $request = $request->withUri($uri->withPath('api/v1/users'));
        // 如果需要偽造查詢引數可以這樣子做
        // $request = $request->withQueryParams([]);
        // 使用全域性函式拿到 App, 傳入偽造的 Request,得到處理之後的 Response
        $response = getApplication()->handle($request);

        // 需要用 (string) 強轉,不要直接 $response->getBody()->getContents()
        // 區別就是強轉,在實現類把讀取指標重置到了第一位,防止得不到完整的內容
        $responseContent = (string)$response->getBody();

        $this->assertJson($responseContent);
    }
}
  • 最後的最後,執行phpunit得到測試結果
$ phpunit
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

..                                                                  2 / 2 (100%)

Time: 45 ms, Memory: 4.00 MB

OK (2 tests, 2 assertions)

原文連結 http://www.shiguopeng.cn/archives/431

當神不再是我們的信仰,那麼信仰自己吧,努力讓自己變好,不辜負自己的信仰!

相關文章