Files
datahub/backend/test/TestCase.php
T

84 lines
2.4 KiB
PHP
Raw Normal View History

2026-03-06 15:29:04 +08:00
<?php
declare(strict_types=1);
namespace HyperfTest;
use Hyperf\HttpServer\MiddlewareManager;
use Hyperf\Testing\Http\TestResponse;
use function Hyperf\Support\make;
/**
* 自定义 TestCase 基类
*
* 修复 Hyperf Testing Client 不处理 PriorityMiddleware 的问题:
* Server.php 在分发请求前会调用 MiddlewareManager::sortMiddlewares()
* 将 PriorityMiddleware 对象转为字符串类名,但 Testing Client 缺少此步骤。
*/
abstract class TestCase extends \Hyperf\Testing\TestCase
{
private bool $middlewaresSorted = false;
protected function doRequest(string $method, ...$args): TestResponse
{
$client = make(\Hyperf\Testing\Http\Client::class);
// Client 构造时触发路由注册,此时排序中间件
if (!$this->middlewaresSorted) {
$this->sortAllRegisteredMiddlewares();
$this->middlewaresSorted = true;
}
if (\Swoole\Coroutine::getCid() > 0) {
return $this->createTestResponse(
$client->{$method}(...$args)
);
}
$response = null;
$exception = null;
\Swoole\Coroutine\run(function () use ($client, $method, $args, &$response, &$exception): void {
try {
$response = $this->createTestResponse(
$client->{$method}(...$args)
);
} catch (\Throwable $throwable) {
$exception = $throwable;
}
});
if ($exception !== null) {
throw $exception;
}
if ($response === null) {
throw new \RuntimeException('Test response not initialized.');
}
return $response;
}
/**
* 将所有已注册的 PriorityMiddleware 对象转为字符串类名
*/
private function sortAllRegisteredMiddlewares(): void
{
$reflection = new \ReflectionClass(MiddlewareManager::class);
$prop = $reflection->getProperty('container');
$prop->setAccessible(true);
$container = $prop->getValue();
foreach ($container as $server => $paths) {
foreach ($paths as $path => $methods) {
foreach ($methods as $method => $middlewares) {
$container[$server][$path][$method] = MiddlewareManager::sortMiddlewares($middlewares);
}
}
}
$prop->setValue(null, $container);
}
}