How can I in PHP re-create my Database (for Unit Testing for example)
Asked Answered
D

3

7

How can I from PHP, re-create my Database, maybe inserting default data. Currently, I am intending to use the behavior for Unit Tests.

I am using Doctrine 2, Zend Framework 1.11, Zend_Test for unit tests

I could use the CLI

doctrine orm:schema-tool:update --force

Or

doctrine orm:schema-tool:drop --force
doctrine orm:schema-tool:create

I am looking for a PHP replacement, so far found this

but it will look something like

$tool = new \Doctrine\ORM\Tools\SchemaTool($em);
$classes = array(
  $em->getClassMetadata('Entities\User'),
  $em->getClassMetadata('Entities\Profile')
);
$tool->dropSchema($classes, \Doctrine\ORM\Tools\SchemaTool::DROP_DATABASE);
$tool->createSchema($classes);

And I don't really want having to specify the model classes, esp in development when they can change. It should just read from the all classes specified in ... below ... just like with the CLI, you don't need to specify the classes you want?

$driverImpl = $config->newDefaultAnnotationDriver(array(realpath('../models')));
$config->setMetadataDriverImpl($driverImpl);
Douzepers answered 17/12, 2010 at 11:45 Comment(5)
(reference) Chapter in PHPUnit on Database testingJovian
@Gordon, thank you, I think that will be the right way to unit test my models, only thing is instead of a PDO connection, how can I use Doctrine's connection? I am using Doctrine 2Douzepers
I'm essentially using the same setup as you, except I pull the list of classes names out of a config, which is easier to maintain. However, I've discovered that calling dropSchema() and createSchema() at every test is really expensive, and a large suite of tests takes forever to run. Using PHPUnit fixtures is much faster. I will have to check out Benjamin's extension as well.Winnick
@Bryan M., But will fixtures take care of database schema changes? Yes, probably I won't be changing database schema everytime, but thats just in case.Douzepers
They won't. My schema changes in-frequently enough that running a manual migration isn't too inconvenient. I also cache my schema to an *.sql which can make re-creating it slightly faster. Just don't run schema-regeneration on every test, and you should be okay.Winnick
J
5

You can use

The PHPUnit Extension for Doctrine offers several hooks into PHPUnits Database extension and offers a very convenient way to test your Doctrine 2 code against a Database.

There is some examples in the Readme, including an example that shows how to create the database schema on the fly. Benjamin Eberlei's is a Doctrine 2 core contributor.

Also see B. Eberlei's Ultimate Guide to DB Testing with PHPUnit

Jovian answered 17/12, 2010 at 14:7 Comment(0)
B
1

Because you have set the path to the models when setting up the EntityManager you can create the schema in code without having to redeclare this path (and without having to declare each class). To do this you need to get a reference to your configured instance of EntityManager and get a reference to ClassMetadataFactory which you can then call ClassMetadataFactory#getAllMedata() from.

Here is an example where I have a static Bootstrap class that allows me to get a reference to the EntityManager from anywhere and I recreate the schema on the setUp() call in the unit tests:

class ModelTestCase extends PHPUnit_Framework_TestCase {

    public function setUp() {
        $em = Bootstrap::getEntityManager();
        $tool = new \Doctrine\ORM\Tools\SchemaTool($em);

        $mdFactory = $em->getMetadataFactory();
        $tool->createSchema($mdFactory->getAllMetadata());
        parent::setUp();
    }
}
Barstow answered 18/8, 2011 at 17:0 Comment(0)
C
0

Doctrine supports fixtures. Try it out.

Cheerio answered 17/12, 2010 at 11:50 Comment(1)
here is a tutorial for symfony: symfony-project.org/blog/2009/10/05/symfony-and-doctrine-2 You have to make your own models manually and persist them.Cheerio

© 2022 - 2024 — McMap. All rights reserved.