Тестирование объекта Doctrine2 с assertEquals приводит к фатальной ошибке нехватки памяти - PullRequest
0 голосов
/ 22 марта 2012

У меня есть тест PHPUnit, использующий пользовательский репозиторий Doctrine2 и Doctrine Fixtures.Я хотел проверить, что запрос вернул мне ожидаемый объект из моего прибора.

Но когда я пытаюсь $this->assertEquals($expectedEntity, $result);, я получаю Fatal error: out of memory.Я предполагаю, что это повторяется во всех отношениях и менеджере сущностей и еще много чего.

Есть ли хороший способ проверить это равенство?Должен ли я просто assertEquals для идентификаторов сущностей?

Edit: Вот тестовый код

<?php
use Liip\FunctionalTestBundle\Test\WebTestCase;

class AbstractRepositoryTestCase extends WebTestCase
{
    /**
     * @var Doctrine\ORM\EntityRepository 
     */
    protected $repo;

    /**
     * @var Doctrine\Common\DataFixtures\Executor\AbstractExecutor
     */
    protected $fixtureExecutor;

    /**
     * @var string Which repository to load, overriden by derived class
     */
    protected $repoName;

    /**
     * @var array Fixture classes to load on setup
     */
    protected $fixtures = array();

    public function setUp()
    {
        $kernel = static::createKernel();
        $this->repo = $kernel->boot();
        $this->repo = $kernel->getContainer()
                             ->get('doctrine.orm.entity_manager')
                             ->getRepository($this->repoName);

        $this->fixtureExecutor = $this->loadFixtures($this->getFixtures());
    }

    public function getFixtures()
    {
        return $this->fixtures;
    }
}

class ArticleRepositoryTest extends AbstractRepositoryTestCase
{
    /**
     * @var string Which repository to load, overriden by derived class
     */
    protected $repoName = 'MyMainBundle:Article';

    /**
     * @var array Fixture classes to load on setup
     */
    protected $fixtures = array(
        'My\MainBundle\DataFixtures\ORM\LoadUserData',
        'My\MainBundle\DataFixtures\ORM\LoadArticleData',
        'My\MainBundle\DataFixtures\ORM\LoadFeedsData',
        'My\MainBundle\DataFixtures\ORM\LoadFeedDataData',
        'My\MainBundle\DataFixtures\ORM\LoadUserReadArticleData',
    );
    public function testGetNextArticle_ExpectCorrect()
    {
        /** @var Doctrine\Common\DataFixtures\ReferenceRepository **/
        $refRepo = $this->fixtureExecutor->getReferenceRepository();

        /** @var FeedStream\MainBundle\Entity\Article **/
        $curr = $refRepo->getReference('feed-1-article-3');
        $expected = $refRepo->getReference('feed-1-article-2');
        $expected2 = $refRepo->getReference('feed-1-article-1');
        $next = $this->repo->getNextArticle($curr->getFeed()->getId(), $curr);

        $this->assertNotNull($next);
        // this is the part that doesn't work
        $this->assertEquals($expected, $next);
        // this is the code I've used instead
        $this->assertEquals($expected->getId(), $next->getId());
    }
}

Вот сущность (геттеры / установщики опущены для сохраненияпробел)

<?php

namespace My\MainBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * My\MainBundle\Entity\Article
 *
 * @ORM\Table(name="articles", uniqueConstraints={
 *   @ORM\UniqueConstraint(name="feed_guid", columns={"feed_id", "guid"}),
 *   @ORM\UniqueConstraint(name="article_slug_unique", columns={"feed_id", "slug"})
 * })
 * @ORM\Entity(repositoryClass="My\MainBundle\Repository\ArticleRepository")
 */
class Article
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @var string $guid
     *
     * @ORM\Column(name="guid", type="string", length=255, nullable=false)
     */
    private $guid;

    /**
     * @var string $title
     *
     * @ORM\Column(name="title", type="string", length=255, nullable=false)
     */
    private $title;

    /**
     * @var datetime $pubDate
     *
     * @ORM\Column(name="pub_date", type="datetime", nullable=true)
     */
    private $pubDate;

    /**
     * @var text $summary
     *
     * @ORM\Column(name="summary", type="text", nullable=true)
     */
    private $summary;

    /**
     * @var text $content
     *
     * @ORM\Column(name="content", type="text", nullable=false)
     */
    private $content;

    /**
     * @var string $sourceUrl
     *
     * @ORM\Column(name="source_url", type="string", length=255, nullable=true)
     */
    private $sourceUrl;

    /**
     * @var string $commentUrl
     *
     * @ORM\Column(name="comment_url", type="string", length=255, nullable=true)
     */
    private $commentUrl;

    /**
     * @var string $slug
     *
     * @ORM\Column(name="slug", type="string", length=64, nullable=false)
     */
    private $slug;

    /**
     * @var string $thumbnailFile
     *
     * @ORM\Column(name="thumbnail_file", type="string", length=64, nullable=true)
     */
    private $thumbnailFile;

    /**
     * @var My\MainBundle\Entity\ArticleEnclosure
     *
     * @ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleEnclosure")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="thumbnail_enclosure_id", referencedColumnName="id")
     * })
     */
    private $thumbnailEnclosure;

    /**
     * @var My\MainBundle\Entity\ArticleImageScrape
     *
     * @ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleImageScrape")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="thumbnail_scrape_id", referencedColumnName="id", unique=false)
     * })
     */
    private $thumbnailScrape;

    /**
     * @var My\MainBundle\Entity\ArticleBitly
     *
     * @ORM\OneToOne(targetEntity="My\MainBundle\Entity\ArticleBitly", mappedBy="article", orphanRemoval=true)
     */
    private $bitly;

    /**
     * @var My\MainBundle\Entity\ArticleEnclosure
     *
     * @ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleEnclosure", mappedBy="article", orphanRemoval=true)
     */
    private $enclosures;

    /**
     * @var My\MainBundle\Entity\ArticleImageScrape
     *
     * @ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleImageScrape", mappedBy="article", orphanRemoval=true)
     */
    private $scrapes;

    /**
     * @var My\MainBundle\Entity\ArticleLink
     *
     * @ORM\OneToMany(targetEntity="My\MainBundle\Entity\ArticleLink", mappedBy="article", orphanRemoval=true)
     */
    private $links;

    /**
     * @var My\MainBundle\Entity\Feed
     *
     * @ORM\ManyToOne(targetEntity="My\MainBundle\Entity\Feed", inversedBy="articles")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="feed_id", referencedColumnName="id", nullable=false)
     * })
     */
    private $feed;

    /**
     * @var My\MainBundle\Entity\ArticleAuthor
     *
     * @ORM\ManyToOne(targetEntity="My\MainBundle\Entity\ArticleAuthor", inversedBy="articles")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     * })
     */
    private $author;

    public function __construct()
    {
        $this->links = new \Doctrine\Common\Collections\ArrayCollection();
    }
}

Ответы [ 2 ]

3 голосов
/ 26 сентября 2013

Если сущности равны, assertEquals нормально работает с сущностями доктрины.

Проблема возникает, когда объекты не совпадают, и тогда phpunit исследует граф entites и никогда не может закончиться в зависимости от вашего графа. К сожалению, параметр maxDepth в assertEquals, похоже, не ограничивает рекурсию, как ожидалось, поэтому я боюсь, что решения:

  • $this->assertEquals($entity1->getId(), $entity2->getId()), который требует сохранения сущностей, и дает идентификатор несоответствующих объектов в случае сбоя

  • $this->assertEquals(spl_object_hash($entity1), spl_object_hash($entity2)) или $this->assertTrue($entity1 === $entity2), которые оба прекрасно работают, но они не дают вам много подробностей о том, в чем различия

  • Лучшее решение ИМХО: преобразовать сущности в массивы с именем класса и свойствами для сравнения массивов:

    use Doctrine \ Common \ Util \ Debug; $ this-> assertEquals (Debug :: export ($ entity1), Debug :: export ($ entity2));

, которая даст вам явную ошибку, говоря, что свойства различны (в этом случае даже класс отличается)

Failed asserting that two objects are equal.
--- Expected
+++ Actual
@@ @@
 stdClass Object (
-    '__CLASS__' => 'Service\Entity\RoleLN'
-    'id' => 'ln_admin'
-    'isApprover' => false
-    'rate' => null
-    'name' => 'ln_admin'
-    'roles' => null
-    'processTasks' => null
+    '__CLASS__' => 'Service\Entity\Role'
+    'id' => 99
+    'rate' => 400
+    'name' => 'roleAdmin'
+    'roleLN' => stdClass Object (...)
+    'organisation' => stdClass Object (...)
+    'users' => null
+    'matterRoles' => Array ()

(Вы можете поместить это сравнение в метод, подобный assertEntitiesEquals)

0 голосов
/ 22 марта 2012

Вы должны также проверить класс в дополнение к ID.

...