symfony Laravel 8中的功能测试使用withHeader设置主机无效?

np8igboo  于 2023-06-06  发布在  其他
关注(0)|答案(2)|浏览(136)

由于我的项目部署了多个域名,需要测试的API接口是以api.example.test域名为入口。
在Feature Test中使用$this->get('/v1/ping')会向www.example.test请求,我希望在ApiFeatureBaseTestCase中的setUp中统一设置$this->withHeader('Host', config('domain.api_domain')),自动向api.example.test Go in请求API相关测试。
但在实践中,我发现这是无效的。通过跟踪代码,我发现了两个可能导致主机设置无效的代码:
第一名(Laravel):
代码在Laravel Framework src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:503中,将参数$uri ='/v1/ping'传入$this->prepareUrlForRequest($uri),得到一个完整的URL,默认为Host,返回值为http://www.example.test/v1/ping
第二名(Symfony):
在Symfony HttpFoundation Component Request.php:355的代码中,将首先使用$uri中的解析。
上述两个代码最终导致withHeader设置的Host I失败。显然,在这个代码逻辑中,Symfony HttpFoundation Component在冲突中对Host的选择不能被认为是错误的,但我提交的这个问题issue在交给Laravel Framework时被关闭了。
我不知道这个问题是bug还是feature
最后,很抱歉我的问题打断了大家的时间,但如果对这个问题有一个结论,请告诉我应该怎样做更合适?
我目前的方法是$this->get($this->api_base_url . '/v1/ping'),但我不认为这是elegant
3Q!!1

代码示例

// File: config/domain.php
return [
    'api_domain' => 'api.example.test',
    'web_domain' => 'www.example.test',
];

// File: routes/demo.php
Route::domain(config('domain.api_domain'))
     ->middleware(['auth:api', 'api.sign.check'])
     ->namespace($this->namespace)
     ->group(function () {
         Route::get('/v1/ping', function () {
             return 'This Api v1';
         });
     });

Route::domain(config('domain.web_domain'))
     ->middleware('web')
     ->namespace($this->namespace)
     ->group(base_path('routes/web.php'));

// File: tests/ApiFeatureBaseTestCase.php
namespace Tests;

class ApiFeatureBaseTestCase extends TestCase
{
    protected function setUp(): void
    {
        parent::setUp();

        $this->withHeader('Host', config('domain.api_domain'));
    }
}

// File: tests/Feature/ApiPingTest.php
namespace Tests\Feature;

use Tests\ApiFeatureBaseTestCase;

class ApiPingTest extends ApiFeatureBaseTestCase
{
    public function testPing()
    {
       $this->get('/v1/ping');
    }
}
ryevplcw

ryevplcw1#

你能在ApiFeatureBaseTestCase类上创建一个 Package 方法吗?

public function get($uri, array $headers = [])
{
    return parent::get(config('domain.api_domain') . $uri, $headers);
}

然后在你的ApiPingTest类中:

public function testPing()
{
    $this->get('/v1/ping');
}
zengzsys

zengzsys2#

我遇到了同样的问题,因为我们有3种类型的子域的应用程序。要解决此问题,您需要更改URL生成器将使用的根URL域,然后再由TestClass使用:

public function setUp(): void
{
        /**
         * We need this to start test application with merchant app type.
         */

        parent::setUp();

        URL::forceRootUrl('http://subdomain.domain.test');
}

现在您可以调用$this->get('/v1/ping');而不指定子域,它将正常工作。
可悲的是,MakesHttpRequests.php:503的问题仍然存在于2023年,你不能像你想的那样从测试中设置host头。
这也适用于并行测试php artisan test --parallel --processes=4

相关问题