首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何为phpUnit模拟EntityManager?

如何为phpUnit模拟EntityManager?
EN

Stack Overflow用户
提问于 2017-02-11 20:48:09
回答 1查看 5.4K关注 0票数 1

我正在为这个类写一个单元测试:

<?php

namespace AppBundle\Managers\CRUD;

use Doctrine\ORM\EntityManager;
use CommonLibs\Interfaces\CrudManagerInterface;
use AppBundle\Entity\Pet;
use CommonLibs\Helpers\PaginatorHelper;
use AppBundle\Entity\Person;
use AppBundle\Managers\CRUD\PetManager;
use AppBundle\AppBundle;

class PersonManager extends CrudManagerInterface
{
    /**
     * @var EntityManager
     */
    private $em;

    /**
     * @var PetManager
     */
    private $petManager;

    public function __construct(EntityManager $em,PetManager $petManager)
    {
        $this->em=$em;
        $this->petManager=$petManager;
    }

    /**
     * {@inheritDoc}
     * @see \CommonLibs\Interfaces\CrudManagerInterface::search()
     * @return AppBundle\Entity\Person[]
     */
    public function search(array $searchParams, array $order, $page, $limit)
    {
        $queryBuilder=$this->em->createQueryBuilder();
        $queryBuilder=$queryBuilder->select('p')->from('AppBundle:Person','p');

        if(isset($searchParams[Person::NAME])) {

            $queryBuilder->andWhere('p.name LIKE :name')->setParameter('name','%'.$searchParams[Person::NAME].'%');
        }

        $petNameSearch=isset($searchParams[Pet::NAME]);
        $petTypeSearch=isset($searchParams[Pet::TYPE]);

        if( $petNameSearch || $petTypeSearch ) {

            $queryBuilder->join('p.pets','pe');

            if($petNameSearch) {

                $queryBuilder->andWhere('pe.name LIKE :pet_name')->setParameter('pet_name','%'.$searchParams[Pet::NAME].'$');
            }

            if($petTypeSearch) {

                if(!is_array($searchParams[Pet::TYPE])) {
                    $searchParams[Pet::TYPE]=array($searchParams[Pet::TYPE]);
                }

                $queryBuilder->andWhere('pe.type IN (:pet_types)')->setParameter('pet_types',$searchParams[Pet::TYPE]);
            }

            /**
             * @var Doctrine\ORM\Query
             */
            $query=$queryBuilder->getQuery();

            if((int)$limit>0) {

                $query->setFirstResult(PaginatorHelper::calculateFirstResult($page,$limit))->setMaxResults((int)$limit);
            }

            $results=$query->getResult();
            return $results;
        }
    }

    /**
     * {@inheritDoc}
     * @see \CommonLibs\Interfaces\CrudManagerInterface::getById()
     * @return AppBundle\Entity\Person
     */
    public function getById($id)
    {
        return $this->em->getManager('AppBundle:Person')->findById($id);
    }


    /**
     * {@inheritDoc}
     * @see \CommonLibs\Interfaces\CrudManagerInterface::add()
     * 
     * @param array $dataToAdd 
     * 
     * $dataToAdd Must have one of the follofiwng formats:
     * 
     * FORMAT 1:
     * [
     *  Person:NAME=>"value"
     * ]
     * 
     * FORMAT 2:
     * 
     * [
     *  [
     *      Person:NAME=>"value"
     *  ],
     *  [
     *      Person:NAME=>"value"
     *  ],
     *  [
     *      Person:NAME=>"value"
     *  ]
     * ]
     * 
     * @return AppBundle\Entiry\Person[] with the modified persons
     */
    public function add(array $dataToAdd)
    {       
        /**
         * @var AppBundle\Entiry\Person $insertedPersons
         */
        $insertedPersons=[];

        foreach($dataToAdd as $key=>$data) {

            $personToInsert=new Person();

            if(is_array($data)) {   

                $personToInsert=$this->add($data);

                if($personToInsert==false) {
                    return false;
                }

            } elseif(!$this->setReference($personToInsert,$key,$data)) {
                $personToInsert->$$key=$data;
            }

            if(is_array($personToInsert)) {
                $insertedPersons=array_merge($insertedPersons,$personToInsert);
            } else {
                $this->em->flush($personToInsert);
                $insertedPersons[]=$personToInsert;
            }
        }

        if(!empty($insertedPersons)) {
            $this->em->flush();
        }

        return $insertedPersons;
    }

    /**
     * {@inheritDoc}
     * @see \CommonLibs\Interfaces\CrudManagerInterface::edit()
     */
    public function edit(array $changedData)
    {
        $em=$this->em->getManager('AppBundle:Person');

        foreach($changedData as $id => $fieldsToChange) {
            $item=$this->getById($id);

            foreach($fieldsToChange as $fieldName=>$fieldValue){
                if(!$this->setReference($item,$fieldName,$fieldValue)){             
                    $item->$$fieldName=$fieldValue;
                }
            }
            $em->merge($item);
        }

        $em->flush();
    }

    /**
     * {@inheritDoc}
     * @see \CommonLibs\Interfaces\CrudManagerInterface::delete()
     * 
     * @param array changedData
     * Should contain data in the following formats:
     * FORMAT 1:
     * 
     * [
     *  Person::ID=>^an_id^
     *  Person::NAME=>^a name of a person^
     * ]
     * 
     * FORMAT2:
     * [
     *  Person::ID=>[^an_id1^,^an_id2^,^an_id3^...,^an_idn^]
     *  Person::NAME=>^a name of a person^
     * ]
     * 
     * The $changedData MUST contain at least one of Person::ID or Person::NAME.
     * Therefore you can ommit one of Person::ID or Person::NAME but NOT both.
     */
    public function delete(array $changedData)
    {
        $queryBuilder=$this->em->createQueryBuilder();

        $queryBuilder->delete()->from('AppBundle:Person','p');

        $canDelete=false;

        if(isset($changedData[Person::ID])) {

            if(!is_array($changedData[Person::ID])) {
                $changedData[Person::ID]=[$changedData[Person::ID]];
            }

            $queryBuilder->where('person.id IN (:id)')->bindParam('id',$changedData[Person::ID]);

            $canDelete=true;
        }

        if(isset($changedData[Person::NAME])) {
            $queryBuilder->orWhere('person.name is :name')->bindParam('name',$changedData[Person::NAME]);
            $canDelete=true;
        }

        if($canDelete) {
            $query=$queryBuilder->getQuery();
            $query->execute();  
        }

        return $canDelete;
    }

    /**
     * Set referencing fields to person.
     * 
     * @param AppBundle\Entiry\Person $item The item to set the reference
     * @param string $referencingKey A string that Indicates the input field.
     *  The strings for the param above are defined as constants at AppBundle\Entiry\Person.
     * @param mixed $referencingValue The value of referencing key
     * 
     * @return boolean
     */
    private function setReference($item,$referencingKey,$referencingValue)
    {
        /**
         * @var AppBundle\Entity\Pet $pet
         */
        $pet=null;

        if($referencingKey===Person::PET) {

            if(is_numeric($referencingValue)) {//Given pet id

                $pet=$this->petManager->getById($referencingValue);//Searching pet by id

            } elseif (is_object($referencingValue) 
                      && $referencingValue instanceof AppBundle\Entity\Pet 
            ){//Given directly a pet Object

                $pet=$referencingValue;

            }

            $item->$$referencingKey=$referencingValue;

            return true;
        }

        return false;
    }

}

我想模拟Doctrine的实体管理器。但是,如果没有实际的数据库连接,我不知道要返回什么才能成功使用Doctrine的查询构建器。

EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42176036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档