由于我的项目已经部署了多个域名,所以需要测试的API接口是使用api.example.test域名作为入口。
使用$this->get('/v1/ping')in Feature Test 会请求到www.example.test,我希望在in 中$this->withHeader('Host', config('domain.api_domain'))统一设置自动请求 API 相关的测试到Go in。setUpApiFeatureBaseTestCaseapi.example.test
但是,在实践中,我发现这是无效的。通过跟踪代码,我发现了两个可能导致无效Host设置的代码:
第一名(Laravel):
Laravel 框架中的代码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 组件Request.php:355$uri的代码中,会先使用解析进来host的,然后默认覆盖在 Header 中Host。
以上两个代码最终导致了HostI set bywithHeader失败。显然,在这段代码逻辑中,不能认为 Symfony HttpFoundation Component 选择 Host in conflict 是错误的,但是我提交这个问题issue给 Laravel Framework 时就关闭了。
我不知道这个问题是a
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');
}
}