84 lines
2.4 KiB
PHP
84 lines
2.4 KiB
PHP
<?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);
|
|
}
|
|
}
|