首页 > 解决方案 > 测试一个 API 控制器 Symfony 4 || 未配置为对实体进行级联持久化操作:

问题描述

首先,我担心我的英语。如果你不明白我真的很抱歉。

我在一个 API 项目上工作,以提高我在 React 和 Symfony 方面的技能。

所以我使用测试驱动开发。我的问题是我使用一些 Fixture 进行测试。

我获得结果的第一条路线还可以。但是当我想要 POST 时,这是另一回事,因为我有 2 ManyTo Relation。

我使用 Liip\TestFixturesBundle\ 作为我的固定装置;

这是我的测试功能:

    public function testAPIProjectPOST(){
        $client = static::createClient();
        $fixtures = $this->loadFixtureFiles([
            __DIR__ . '/../Fixtures/DataBaseFixture.yaml'
        ]);
        $parameters = [
            'name' => "ProjectTestAPI",
            'description' => "First Project in POST",
            'difficulty' => 4,
            'skills' => [1],
            'owner' => 1
        ];
        $client->request('POST','/api/project',[],[],['CONTENT_TYPE'=>'application/json'],json_encode($parameters));
        $content = $client->getResponse();
        $this->assertResponseStatusCodeSame(Response::HTTP_CREATED);

    }

我收到这些错误:

A new entity was found through the relationship 'App\Entity\Project#skills' that was not configured to cascade persist operations for entity: App\Entity\Skill@00000000726fccc80000000059a1c5e2. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Entity\Skill#__toString()' to get a clue.
 * A new entity was found through the relationship 'App\Entity\Project#owner' that was not configured to cascade persist operations for entity: App\Entity\User@00000000726fcd310000000059a1c5e2. To solve this issue: Either explicitly call EntityManager#persist() on this unknown entity or configure cascade persist this association in the mapping for example @ManyToOne(..,cascade={"persist"}). If you cannot find out which entity causes the problem implement 'App\Entity\User#__toString()' to get a clue. (500 Internal Server Error) -->

非常感谢您的回答!

更新:更多代码

数据夹具.yaml:

App\Entity\User:
  user{1..10}:
    username: user<current()>
    email: user<current()>\@domain.fr
    password: '0000'

App\Entity\Skill:
  skill{1..3}:
    name: skill<current()>

App\Entity\Project:
  project{1..10}:
    name: project<current()>
    description: Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean egestas id eros sit amet maximus. Donec fringilla diam et elementum ultricies.
    owner: '@user<current()>'
    difficulty: <numberBetween(1,5)>
    skills: ['@skill<numberBetween(1,3)>']

页面控制器.php

<?php

namespace App\Controller;

use App\Entity\Project;
use App\Repository\ProjectRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
use Symfony\Component\Serializer\SerializerInterface;
use Symfony\Component\Validator\Validator\ValidatorInterface;

class ApiProjectController extends AbstractController
{
    /**
     * @Route("/api/project", name="api_project", methods={"GET"})
     */
    public function index(ProjectRepository $projectRepository)
    {
        return $this->json($projectRepository->findAll(),200,[],['groups'=>'project:read']);
    }

    /**
     * @Route("/api/project", name="api_project_store", methods={"POST"})
     */
    public function store(Request $request,SerializerInterface $serializer,EntityManagerInterface $em,ValidatorInterface $validator){
        $json = $request->getContent();
        try{
            $post = $serializer->deserialize($json, Project::class,'json');

            $errors = $validator->validate($post);

            if (count($errors)>0){
                return $this->json($errors,400);
            }

            $em->persist($post);
            $em->flush();

            return $this->json($post,201,[],['groups'=>'read']);
        }
        catch(NotEncodableValueException $e){
            return $this->json([
                'status'=>400,
                'message'=> $e->getMessage()
            ],400);
        }
    }
}

标签: entity-frameworksymfony

解决方案


解决方案 :

我添加了我的后期控制器、UserRepository 和 SkillRepository。

    public function store(Request $request,SerializerInterface $serializer,EntityManagerInterface $em,ValidatorInterface $validator,UserRepository $userRepository,SkillRepository $skillRepository){
    $json = $request->getContent();
    try{
        $project = $serializer->deserialize($json, Project::class,'json');
        $project->setOwner($userRepository->find(json_decode($json)->owner));
        $project->initializeSkills();
        foreach(json_decode($json)->skills as $idSkill){
            $project->addSkill($skillRepository->find($idSkill));
        }
        $errors = $validator->validate($project);

        if (count($errors)>0){
            return $this->json($errors,400);
        }

        $em->persist($project);
        $em->flush();

        return $this->json($project,201,[],['groups'=>'project:read']);
    }
    catch(NotEncodableValueException $e){
        return $this->json([
            'status'=>400,
            'message'=> $e->getMessage()
        ],400);
    }
}

推荐阅读