Api 平台:如何使用 ApiTestCase 测试文件上传
Api Platform: how to test file upload with ApiTestCase
我有一个允许文件上传的端点,一切正常。
接下来是用适当的功能测试覆盖端点。
这就是问题所在 - 我无法将 file
传递给发出请求的客户端。
我的测试 class 扩展 \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase
.
static::createClient()
方法创建 ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client
的实例,这些 Client
不支持文件上传。
因为实现了定义 public function request(string $method, string $url, array $options = []): ResponseInterface;
的 Symfony\Contracts\HttpClient\HttpClientInterface
,所以没有地方可以传递 files
参数。
Client
中允许的options
不支持files
数组。
内部看起来像这样:
ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client::request
向内部 kernelBrowser
传递一个空数组代替 files
参数(第二个数组):$this->kernelBrowser->request($method, $resolvedUrl, [], [], $server, $options['body'] ?? null)
如何通过扩展 Base class for functional API tests
即 ApiTestCase
来测试文件上传端点?
下面是一些代码,可以帮助您直观地了解问题:
Api实体中的资源定义:
/**
* @ApiResource(
* collectionOperations={
* "file_upload"={
* "method"="post",
* "controller"=FileUpload::class,
* "path"="/api/file-upload-endpoint",
* "deserialize"=false,
* "openapi_context"={
* "requestBody"={
* "content"={
* "multipart/form-data"={
* "schema"={
* "type"="object",
* "properties"={
* "file"={
* "type"="string",
* "format"="binary"
* }
* }
* }
* }
* }
* }
* }
* },
* },
* )
*/
测试class(不要介意UploadedFile
的实例,它就在那里,告诉你,它不能被传递到任何地方):
<?php
declare(strict_types=1);
namespace App\Tests\Api;
use \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
final class FileUploadTest extends ApiTestCase
{
public function testFileUploadSuccessfully():void
{
$file = new UploadedFile(
TESTS_PROJECT_DIR.'/tests/files/Small_sample_of_jet.jpg',
'Small_sample_of_jet.jpg',
'image/jpeg',
);
static::createClient()->request(
'POST',
'/api/file-upload-endpoint',
[
'headers' => [
'Content-Type' => 'multipart/form-data',
],
],
);
self::assertResponseIsSuccessful();
self::assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
}
}
这就是我要找的东西:
<?php
declare(strict_types=1);
namespace App\Tests\Api;
use \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
final class FileUploadTest extends ApiTestCase
{
public function testFileUploadSuccessfully():void
{
$file = new UploadedFile(
TESTS_PROJECT_DIR.'/tests/files/Small_sample_of_jet.jpg',
'Small_sample_of_jet.jpg',
'image/jpeg',
);
static::createClient()->request(
'POST',
'/api/file-upload-endpoint',
[
'headers' => [
'Content-Type' => 'multipart/form-data',
],
],
[
'file'=>$file
]
);
self::assertResponseIsSuccessful();
self::assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
}
}
当修改 vendor
本身并将 files
传递给 Client::request
然后传递给 kernelBrowser
代替第二个空数组时,一切正常(我我知道违约,这不是这里的问题 ;))。
我在想ApiTestCase
是不是缺少上传文件的功能,或者我就是找不到解决办法
请暂停!
Api平台版本:2.5.6
PS:我知道我可以使用不同的客户端 - test.client
$client = static::$kernel->getContainer()->get('test.client');
这是 Symfony\Bundle\FrameworkBundle\KernelBrowser
的一个实例,与 Api 平台的 Client
内部使用的相同,并且 支持 files
数组,但这不是我的问题的重点。我想知道如何使用 ApiTestCase
.
上传文件
自从当前最新版本 api-platform/core
(2.5.8) 以来,我们可以通过 extra
键将更多参数传递给 kernelBrowser->request
。这现在也包括文件!
下面是一个非常基本的图片上传测试示例(基于official API Platform documentation实现):
$file = new UploadedFile(
'path/to/images/my_image.png',
'my_image.png',
'image/png',
);
$response = static::createClient()->request('POST', '/upload_image',
[
'headers' => ['Content-Type' => 'multipart/form-data'],
'extra' => [
'files' => [
'file' => $file,
],
],
],
);
我有一个允许文件上传的端点,一切正常。
接下来是用适当的功能测试覆盖端点。
这就是问题所在 - 我无法将 file
传递给发出请求的客户端。
我的测试 class 扩展 \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase
.
static::createClient()
方法创建 ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client
的实例,这些 Client
不支持文件上传。
因为实现了定义 public function request(string $method, string $url, array $options = []): ResponseInterface;
的 Symfony\Contracts\HttpClient\HttpClientInterface
,所以没有地方可以传递 files
参数。
Client
中允许的options
不支持files
数组。
内部看起来像这样:
ApiPlatform\Core\Bridge\Symfony\Bundle\Test\Client::request
向内部 kernelBrowser
传递一个空数组代替 files
参数(第二个数组):$this->kernelBrowser->request($method, $resolvedUrl, [], [], $server, $options['body'] ?? null)
如何通过扩展 Base class for functional API tests
即 ApiTestCase
来测试文件上传端点?
下面是一些代码,可以帮助您直观地了解问题:
Api实体中的资源定义:
/**
* @ApiResource(
* collectionOperations={
* "file_upload"={
* "method"="post",
* "controller"=FileUpload::class,
* "path"="/api/file-upload-endpoint",
* "deserialize"=false,
* "openapi_context"={
* "requestBody"={
* "content"={
* "multipart/form-data"={
* "schema"={
* "type"="object",
* "properties"={
* "file"={
* "type"="string",
* "format"="binary"
* }
* }
* }
* }
* }
* }
* }
* },
* },
* )
*/
测试class(不要介意UploadedFile
的实例,它就在那里,告诉你,它不能被传递到任何地方):
<?php
declare(strict_types=1);
namespace App\Tests\Api;
use \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
final class FileUploadTest extends ApiTestCase
{
public function testFileUploadSuccessfully():void
{
$file = new UploadedFile(
TESTS_PROJECT_DIR.'/tests/files/Small_sample_of_jet.jpg',
'Small_sample_of_jet.jpg',
'image/jpeg',
);
static::createClient()->request(
'POST',
'/api/file-upload-endpoint',
[
'headers' => [
'Content-Type' => 'multipart/form-data',
],
],
);
self::assertResponseIsSuccessful();
self::assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
}
}
这就是我要找的东西:
<?php
declare(strict_types=1);
namespace App\Tests\Api;
use \ApiPlatform\Core\Bridge\Symfony\Bundle\Test\ApiTestCase;
use Symfony\Component\HttpFoundation\File\UploadedFile;
final class FileUploadTest extends ApiTestCase
{
public function testFileUploadSuccessfully():void
{
$file = new UploadedFile(
TESTS_PROJECT_DIR.'/tests/files/Small_sample_of_jet.jpg',
'Small_sample_of_jet.jpg',
'image/jpeg',
);
static::createClient()->request(
'POST',
'/api/file-upload-endpoint',
[
'headers' => [
'Content-Type' => 'multipart/form-data',
],
],
[
'file'=>$file
]
);
self::assertResponseIsSuccessful();
self::assertResponseHeaderSame('content-type', 'application/ld+json; charset=utf-8');
}
}
当修改 vendor
本身并将 files
传递给 Client::request
然后传递给 kernelBrowser
代替第二个空数组时,一切正常(我我知道违约,这不是这里的问题 ;))。
我在想ApiTestCase
是不是缺少上传文件的功能,或者我就是找不到解决办法
请暂停!
Api平台版本:2.5.6
PS:我知道我可以使用不同的客户端 - test.client
$client = static::$kernel->getContainer()->get('test.client');
这是 Symfony\Bundle\FrameworkBundle\KernelBrowser
的一个实例,与 Api 平台的 Client
内部使用的相同,并且 支持 files
数组,但这不是我的问题的重点。我想知道如何使用 ApiTestCase
.
自从当前最新版本 api-platform/core
(2.5.8) 以来,我们可以通过 extra
键将更多参数传递给 kernelBrowser->request
。这现在也包括文件!
下面是一个非常基本的图片上传测试示例(基于official API Platform documentation实现):
$file = new UploadedFile(
'path/to/images/my_image.png',
'my_image.png',
'image/png',
);
$response = static::createClient()->request('POST', '/upload_image',
[
'headers' => ['Content-Type' => 'multipart/form-data'],
'extra' => [
'files' => [
'file' => $file,
],
],
],
);