Since my project has deployed multiple domain names, the API interface that needs to be tested is using the api.example.test
domain name as the entrance.
Using $this->get('/v1/ping')
in Feature Test will request to www.example.test
, I hope to set up $this->withHeader('Host', config('domain.api_domain'))
uniformly in setUp
in ApiFeatureBaseTestCase
to automatically request API related tests to api.example.test
Go in.
However, in practice, I found that this is invalid. By tracing the code, I found two codes that may cause the invalid Host setting:
First place (Laravel):
Code in Laravel Framework src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:503, pass the parameter $uri ='/v1/ping'
into $this->prepareUrlForRequest($uri)
and get a complete Url with the default Host, the return value is http://www.example.test/v1/ping
.
Second place (Symfony):
In the code of Symfony HttpFoundation Component Request.php:355, the parsing in $uri
will be used first The coming out host
is overwritten in the Header as the default Host
.
The above two codes eventually caused the Host
I set by withHeader
to fail. Obviously, in this code logic, Symfony HttpFoundation Component's choice of Host in conflict cannot be considered wrong, but I submitted this question issue was closed when it was given to Laravel Framework.
I don't know if this issue is a
bug
orfeature
?
Finally, I am sorry that my question has interrupted everyone's time, but if there is a conclusion on this question, please tell me what should be more appropriate?
My current approach is $this->get($this->api_base_url . '/v1/ping')
, but I don’t think this is elegant
3Q!!1
Code example
// 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');
}
}
Can you create a wrapper method on your
ApiFeatureBaseTestCase
class?Then in your
ApiPingTest
class: