由于我的项目已经部署了多个域名,所以需要测试的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。setUp
ApiFeatureBaseTestCase
api.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
。
以上两个代码最终导致了Host
I 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');
}
}