由于我的项目部署了多个域名,需要测试的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');
}
}
2条答案
按热度按时间ryevplcw1#
你能在
ApiFeatureBaseTestCase
类上创建一个 Package 方法吗?然后在你的
ApiPingTest
类中:zengzsys2#
我遇到了同样的问题,因为我们有3种类型的子域的应用程序。要解决此问题,您需要更改URL生成器将使用的根URL域,然后再由TestClass使用:
现在您可以调用
$this->get('/v1/ping');
而不指定子域,它将正常工作。可悲的是,
MakesHttpRequests.php:503
的问题仍然存在于2023年,你不能像你想的那样从测试中设置host
头。这也适用于并行测试
php artisan test --parallel --processes=4