【问题标题】:How to check if Doctrine entity is persisted and flushed to database?如何检查 Doctrine 实体是否被持久化并刷新到数据库?
【发布时间】:2015-04-22 08:51:43
【问题描述】:

我想编写一个测试用例,通过 Doctrine 实体管理器验证一个实体是否已完全持久化到数据库中。

例如:

<?php

function notPersisted() {
    return new Entity();
}

function persistedButNotFlushed() {
    $entity = new Entity();
    $entityManager->persist($entity);

    return $entity;
}

function persistedAndFlushed() {
    $entity = new Entity();
    $entityManager->persist($entity);
    $entityManager->flush();

    return $entity;
}

function persistedButNotAllChangesFlushed() {
    $entity = new Entity();
    $entityManager->persist($entity);
    $entityManager->flush();

    $entity->setFoo('bar');
    $entityManager->persist($entity);

    return $entity;
}

$this->assertNotPersistedToDb(notPersisted());
$this->assertNotPersistedToDb(persistedButNotFlushed());
$this->assertPersistedToDb(persistedAndFlushed());
$this->assertNotPersistedToDb(persistedButNotAllChangesFlushed());

你会怎么做呢?

【问题讨论】:

  • $entityManager-&gt;getUnitOfWork()-&gt;getScheduledEntityInsertions() 看起来很合适,不是吗?看到您实际上是在尝试断言 UnitOfWork 将是什么... See what else you can do
  • 看起来您正在测试 D2 功能。可能需要重新考虑这些测试是否真的能完成任何事情。

标签: php doctrine-orm doctrine phpunit


【解决方案1】:

这是我想出的:

protected function assertEntityIsPersistedToDb($entity) {
    $unitOfWork = $this->entityManager->getUnitOfWork();
    $isManaged = $this->entityManager->contains($entity);
    $isFlushedToDb = !$unitOfWork->isEntityScheduled($entity);

    $id = $this->getEntityId($entity);

    $entityClassName = get_class($entity);
    $msg = "Expected entity of type $entityClassName to be persisted to the database, ";

    if (!$id) {
        $msg .= "but the entity does not have an id.";
    }
    else if (!$isManaged) {
        $msg .= "but entity is not managed by the entity manager.";
    }
    else if (!$isFlushedToDb) {
        $msg .= "but the entity has changes which have not yet been flushed.";
    }

    $this->assertTrue(!!$id && $isManaged && $isFlushedToDb, $msg);
}

protected function assertEntityNotPersistedToDb($entity) {
    // Ensure that this is a managed entity
    if (!$this->entityManager->contains($entity)) {
        throw new \PHPUnit_Framework_ExpectationFailedException(
            "Unable to determine if entity is persisted to DB: the entity is not managed."
        );
        // Alternatively, we could maybe do an $em->merge($entity),
        // and then check its state. However, this could change our application
        // state, and potential effect test behavior.
    }

    $isFlushedToDb = !$this->entityManager->getUnitOfWork()
        ->isEntityScheduled($entity);

    $entityClass = get_class($entity);
    $msg = "Expected entity of type $entityClass not to be persisted to the database.";

    $this->assertFalse($isFlushedToDb, $msg);
}


protected function getEntityId($entity) {
    $idList = $this->entityManager
        ->getClassMetadata(get_class($entity))
        ->getIdentifier();

    return empty($idList) ?
        null : call_user_func([$entity, 'get' . ucfirst(reset($idList))]);
}

我用它玩了一会儿,它似乎工作,虽然我还没有通过任何严格的测试。

【讨论】:

    【解决方案2】:

    根据您的工作,当您的对象中有多个关联并且您的级联选项设置不正确时,分离可能会很痛苦,这两个函数可以帮助您断言实体是否在您的应用程序状态中进行管理。

    static function assertEntityIsManaged(EntityManager $em, $entity) {
        $isManaged = $em->contains($entity);
        $entityClass = get_class($entity);
        $msg = "Expected entity of type $entityClass IS NOT Managed";
        assert($isManaged === TRUE, $msg);
    }
    
    static function assertEntityNotManaged(EntityManager $em, $entity) {
        $isManaged = $em->contains($entity);
        $entityClass = get_class($entity);
        $msg = "Expected entity of type $entityClass IS Managed";
        assert($isManaged === FALSE, $msg);
    }
    

    静态,因为它不是“正式”测试,而且我有多个实体管理器实例。

    【讨论】:

      猜你喜欢
      • 2018-03-18
      • 2022-10-24
      • 1970-01-01
      • 2013-04-12
      • 1970-01-01
      • 1970-01-01
      • 2016-04-13
      • 2012-01-30
      • 1970-01-01
      相关资源
      最近更新 更多