ApiTestCase 中不返回子实体链接,但在其他地方有效
Child entity links are not returned in ApiTestCase but work elsewhere
我有两个实体,一个客户端(访问器被剪断)
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(
* collectionOperations={
* "get"={"normalization_context"={"groups"="client:list"}},
* "post"
* },
* itemOperations={
* "get"={"normalization_context"={"groups"="client:item"}},
* },
* paginationEnabled=false,
* order={"name"="ASC"}
* )
* @ORM\Entity(repositoryClass="App\Repository\ClientRepository")
*/
class Client
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"client:list", "client:item"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
* @Groups({"client:list", "client:item"})
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Package", mappedBy="client")
* @Groups({"client:item"})
*/
private $packages;
public function __construct()
{
$this->packages = new ArrayCollection();
}
还有一个包裹:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* collectionOperations={
* "get"={"normalization_context"={"groups"="package:list"}},
* "post"={"denormalization_context"={"groups"="package:list"}},
* },
* itemOperations={
* "get"={"normalization_context"={"groups"="package:item"}},
* "delete",
* },
*
* )
* @ApiFilter(SearchFilter::class, properties={"client": "exact"})
* @ORM\Entity(repositoryClass="App\Repository\PackageRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Package
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"package:list", "package:item"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"package:list", "package:item"})
*/
private $name;
/**
* @ORM\Column(type="datetime")
* @Groups({"package:item"})
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Client", inversedBy="packages")
* @ORM\JoinColumn(nullable=false)
* @Groups({"package:list", "package:item"})
*/
private $client;
/**
* @ORM\Column(type="string", length=64)
*/
private $status;
当我查看 API 浏览器(或在 cli 上使用 cURL)并查询单个客户端时,我可以看到响应中返回了子包实体(请求为 JSON只是为了让有效载荷更清晰):
{
"id": 1,
"name": "First Client",
"packages": [
"/api/packages/1",
"/api/packages/2"
]
}
但是,在我的测试用例中,没有返回子实体。我的测试如下所示:
public function testItShouldReturnASpecificClient(): void
{
$client = static::createClient();
$response = $client->request('GET', '/api/clients/1', ['headers' => ['Accept' => 'application/json']]);
$data = json_decode($response->getContent(), false);
static::assertSame(1, $data->id);
static::assertCount(2, $data->packages);
}
第二个断言失败了。当我转储响应时,我可以看到包 属性 尚未填充:
class stdClass#1937 (3) {
public $id =>
int(1)
public $name =>
string(12) "First Client"
public $packages =>
array(0) {
}
}
我在这里缺少什么才能使它的行为与 API 在测试之外的行为一样?
问题一直出在我的固定装置上,感谢@ihsan 指导我进行调试。
我之前假设我需要做的就是link打包给客户:
App\Entity\Package:
package_1:
name: 'Inactive Package For First Client'
createdAt: <dateTime('today -1 year')>
status: 'INACTIVE'
client: '@client_1'
package_2:
name: 'Active Package For First Client'
createdAt: <dateTime('today -1 week')>
status: 'ACTIVE'
client: '@client_1'
但是,为了使测试正常工作,我还必须将包关联到客户端:
App\Entity\Client:
client_1:
name: First Client
packages:
- '@package_1'
- '@package_2'
我有两个实体,一个客户端(访问器被剪断)
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiResource;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
use Symfony\Component\Validator\Constraints as Assert;
/**
* @ApiResource(
* collectionOperations={
* "get"={"normalization_context"={"groups"="client:list"}},
* "post"
* },
* itemOperations={
* "get"={"normalization_context"={"groups"="client:item"}},
* },
* paginationEnabled=false,
* order={"name"="ASC"}
* )
* @ORM\Entity(repositoryClass="App\Repository\ClientRepository")
*/
class Client
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"client:list", "client:item"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Assert\NotBlank
* @Groups({"client:list", "client:item"})
*/
private $name;
/**
* @ORM\OneToMany(targetEntity="App\Entity\Package", mappedBy="client")
* @Groups({"client:item"})
*/
private $packages;
public function __construct()
{
$this->packages = new ArrayCollection();
}
还有一个包裹:
<?php
namespace App\Entity;
use ApiPlatform\Core\Annotation\ApiFilter;
use ApiPlatform\Core\Annotation\ApiResource;
use ApiPlatform\Core\Bridge\Doctrine\Orm\Filter\SearchFilter;
use DateTime;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* @ApiResource(
* collectionOperations={
* "get"={"normalization_context"={"groups"="package:list"}},
* "post"={"denormalization_context"={"groups"="package:list"}},
* },
* itemOperations={
* "get"={"normalization_context"={"groups"="package:item"}},
* "delete",
* },
*
* )
* @ApiFilter(SearchFilter::class, properties={"client": "exact"})
* @ORM\Entity(repositoryClass="App\Repository\PackageRepository")
* @ORM\HasLifecycleCallbacks()
*/
class Package
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
* @Groups({"package:list", "package:item"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"package:list", "package:item"})
*/
private $name;
/**
* @ORM\Column(type="datetime")
* @Groups({"package:item"})
*/
private $createdAt;
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Client", inversedBy="packages")
* @ORM\JoinColumn(nullable=false)
* @Groups({"package:list", "package:item"})
*/
private $client;
/**
* @ORM\Column(type="string", length=64)
*/
private $status;
当我查看 API 浏览器(或在 cli 上使用 cURL)并查询单个客户端时,我可以看到响应中返回了子包实体(请求为 JSON只是为了让有效载荷更清晰):
{
"id": 1,
"name": "First Client",
"packages": [
"/api/packages/1",
"/api/packages/2"
]
}
但是,在我的测试用例中,没有返回子实体。我的测试如下所示:
public function testItShouldReturnASpecificClient(): void
{
$client = static::createClient();
$response = $client->request('GET', '/api/clients/1', ['headers' => ['Accept' => 'application/json']]);
$data = json_decode($response->getContent(), false);
static::assertSame(1, $data->id);
static::assertCount(2, $data->packages);
}
第二个断言失败了。当我转储响应时,我可以看到包 属性 尚未填充:
class stdClass#1937 (3) {
public $id =>
int(1)
public $name =>
string(12) "First Client"
public $packages =>
array(0) {
}
}
我在这里缺少什么才能使它的行为与 API 在测试之外的行为一样?
问题一直出在我的固定装置上,感谢@ihsan 指导我进行调试。
我之前假设我需要做的就是link打包给客户:
App\Entity\Package:
package_1:
name: 'Inactive Package For First Client'
createdAt: <dateTime('today -1 year')>
status: 'INACTIVE'
client: '@client_1'
package_2:
name: 'Active Package For First Client'
createdAt: <dateTime('today -1 week')>
status: 'ACTIVE'
client: '@client_1'
但是,为了使测试正常工作,我还必须将包关联到客户端:
App\Entity\Client:
client_1:
name: First Client
packages:
- '@package_1'
- '@package_2'