4
votes

I am currently trying to test my doctrine2.2 objects with phpUnit to do I am using the doctrine extensions which can be found here.

This is a base class which all my phpUnit TestClass extend.

<?php
use DoctrineExtensions\PHPUnit\Event\EntityManagerEventArgs,
    DoctrineExtensions\PHPUnit\OrmTestCase,
    Doctrine\ORM\Tools\SchemaTool,
    Doctrine\Common\EventManager,
    Doctrine\ORM\Tools\Setup,
    Doctrine\ORM\EntityManager;

class SchemaSetupListener {
    public function preTestSetUp(EntityManagerEventArgs $eventArgs) {
        $em = $eventArgs->getEntityManager();
        $schemaTool = new SchemaTool($em);
        $cmf = $em->getMetadataFactory();
        $classes = $cmf->getAllMetadata();
        $schemaTool->dropDatabase();
        $schemaTool->createSchema($classes);
    }
}

class EntityFunctionalTest extends OrmTestCase {

    protected function createEntityManager() {
        $config = Setup::createXMLMetadataConfiguration(array(DIR_XML_SCHEMA), true); // dev mode true
        $conn = array('driver' => 'pdo_sqlite', 'path' =>  DIR_TEST_SUITE_ROOT . 'test.db');
        $conn = array('driver' => 'pdo_sqlite', 'memory' => true);
        $eventManager = new EventManager();
        $eventManager->addEventListener(array("preTestSetUp"), new SchemaSetupListener());
        return Doctrine\ORM\EntityManager::create( $conn, $config, $eventManager);
    }

    protected function getDataSet() {
        return $this->createFlatXmlDataSet(DIR_XML_TEST_DATA . 'db.boot.strap.test.flat.xml');
    }

    protected function tearDown(){
        $entityManager = $this->getEntityManager();
        $entityManager->flush();
        $entityManager->getConnection()->getConfiguration()->setSQLLogger(null);;
        $entityManager->close();
    }

    public function getSystemUser(){
        return $this->getEntityManager()->createQuery('select u from User u where u.id = 1')->getSingleResult();
    }
}

?>

When I have the following commented out below, so that sqlite is not creating its database in memory everything works but it is slow.

$conn = array('driver' => 'pdo_sqlite', 'path' =>  DIR_TEST_SUITE_ROOT . 'test.db');
//$conn = array('driver' => 'pdo_sqlite', 'memory' => true);

When I uncomment the line and try to run the tests using a slqlite database in memory, only the first test function get data from getDataSet() method (when I run this using a sqlite database everything is fine).

Why is the getDataSet() method only working, for the first test method?

Here is the output of me running the test in the command line:

C:\TestSuite\phpUnit\testsuites>phpUnit --configuration al

lTests.xml
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from C:\TestSuite\phpUnit\testsuites\al
lTests.xml

.E

Time: 1 second, Memory: 16.00Mb

There was 1 error:

1) UserTest::testId
Doctrine\ORM\NoResultException: No result was found for query although at least
one row was expected.

C:\Program Files (x86)\PHP\PEAR\Doctrine\ORM\AbstractQuery.php:491
C:\TestSuite\phpUnit\testsuites\classes\entities\EntityFun
ctionalTest.php:43
C:\TestSuite\phpUnit\testsuites\classes\entities\UserTest.
php:60
C:\Program Files (x86)\PHP\phpunit:46

FAILURES!
Tests: 2, Assertions: 8, Errors: 1.
2

2 Answers

4
votes

I had same problem and solution was to share entity manager between test:

protected static $em = null;

public static function setUpBeforeClass()
{
    $isDevMode = true;
    $config = Setup::createAnnotationMetadataConfiguration(array(__DIR__."/../src"), $isDevMode, null, null, false);

    $connectionOptions = array('driver' => 'pdo_sqlite', 'memory' => true);

    // obtaining the entity manager
    self::$em =  EntityManager::create($connectionOptions, $config);

    $schemaTool = new SchemaTool(self::$em);

    $cmf = self::$em->getMetadataFactory();
    $classes = $cmf->getAllMetadata();

    $schemaTool->dropDatabase();
    $schemaTool->createSchema($classes);

}

public static function tearDownAfterClass()
{
    self::$em = NULL;
}

protected function createEntityManager()
{


    return self::$em;
}
0
votes

In addition to what @Zedenek Machek said: from the point of view of loosely coupling your test, sharing fixtures should be avoided:

It cannot be emphasized enough that sharing fixtures between tests reduces the value of the tests. The underlying design problem is that objects are not loosely coupled. You will achieve better results solving the underlying design problem and then writing tests using stubs (see Chapter 9), than by creating dependencies between tests at runtime and ignoring the opportunity to improve your design.

see https://phpunit.de/manual/current/en/fixtures.html#fixtures.sharing-fixture.examples.DatabaseTest.php