Skip to content

OSS PHP Frameworks Unit Testing: Doctrine

ptarjan edited this page Oct 16, 2013 · 4 revisions

Doctrine 2 is an object-relational mapper (ORM) for PHP that provides transparent persistence for PHP objects.

Source Download

Download the latest master branch from Github

Official Testing Documentation

The documentation to run the unit tests are found here: https://github.com/doctrine/doctrine2/blob/master/tests/README.markdown

The documentation above is generally sparse, but the overall takeaway is that PHPUnit can be used "out of the box" to test Doctrine, after some initial setup steps are taken.

Initial Setup

In order to run the Doctrine unit tests successfully, make sure you have HHVM, Composer and other basic packages ready to go.

Some initial configuration is required for Doctrine, particularly around a sample database and dependencies.

Sample Database

A sample database is necessary to run the unit tests. We used MySQL to setup the sample database. There are many links online to help install MySQL on CentOS 6. Here is one: http://centoshelp.org/servers/database/installing-configuring-mysql-server/

The following SQL was used to create the test database:

CREATE DATABASE doctrine_tests;
CREATE USER 'doctrineuser'@'127.0.0.1' IDENTIFIED BY 'mypass';
GRANT ALL PRIVILEGES ON doctrine_tests.* TO 'doctrineuser'@'127.0.0.1';
GRANT CREATE, DROP, FILE ON *.* TO 'doctrineuser'@'127.0.0.1';
CREATE USER 'doctrineuser'@'localhost' IDENTIFIED BY 'mypass';
GRANT ALL PRIVILEGES ON doctrine_tests.* TO 'doctrineuser'@'localhost';
GRANT CREATE, DROP, FILE ON *.* TO 'doctrineuser'@'localhost';

In the file phpunit.xml.dist (found in the root Doctrine directory), the database credential changes were made:

<php>
    <!-- "Real" test database -->
    <!-- uncomment, otherwise sqlite memory runs -->
    <var name="db_type" value="pdo_mysql"/>
    <var name="db_host" value="127.0.0.1" />
    <var name="db_username" value="doctrineuser" />
    <var name="db_password" value="mypass" />
    <var name="db_name" value="doctrine_tests" />
    <var name="db_port" value="3306"/>-->
    <var name="db_event_subscribers" value="Doctrine\DBAL\Event\Listeners\OracleSessionInit">

    <!-- Database for temporary connections (i.e. to drop/create the main database) -->
    <var name="tmpdb_type" value="pdo_mysql"/>
    <var name="tmpdb_host" value="127.0.0.1" />
    <var name="tmpdb_username" value="doctrineuser" />
    <var name="tmpdb_password" value="mypass" />
    <var name="tmpdb_name" value="doctrine_tests" />
    <var name="tmpdb_port" value="3306"/>
  </php>

Dependencies

We used composer to install the dependencies. In the root Doctrine directory, you will find the composer.json file that will be used to download the required dependencies to run the unit tests.

hhvm [path-to-composer-phar]/composer.phar install --dev

Running the Tests

We used our phpunit binary to run the unit tests. To run the Doctrine unit tests, use the following command from the root Doctrine directory:

`hhvm [path-to-vendor-parent]/vendor/bin/phpunit`

Fatals

Interfaces

The database functionality caused immediate fatals:

HipHop Fatal error: Declaration of Doctrine\DBAL\Driver\PDOConnection::query() must be compatible with that of Doctrine\DBAL\Driver\Connection::query() in /data/users/joelm/php-open-source-projects/doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php on line 30

In doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:

class PDOConnection extends PDO implements Connection

Not all of the methods of Connection in doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Connection.php were implemented in PDOConnection.

HipHop Fatal error: Access level to Doctrine\DBAL\Driver\PDOStatement::__construct() must be protected (as in class PDOStatement) or weaker in /data/users/joelm/php-open-source-projects/doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php on line 28

The file affected here was: doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php.

PDOStatement (http://php.net/manual/en/class.pdostatement.php) does not have a public constructor, but does have a protected one.

Declaration of Doctrine\DBAL\Driver\PDOStatement::bindValue() must be compatible with that of Doctrine\DBAL\Driver\Statement::bindValue() in /data/users/joelm/php-open-source-projects/doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php on line 28

The files involved here were:

doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php
doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/Statement.php
doctrine2/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/ResultStatement.php

It would seem, on the surface, that Doctrine/DBAL/Driver/PDOStatement.php needs to implement ALL interface methods (except setFetchMode, which was implemented) of Doctrine/DBAL/Driver/Statement.php and Doctrine/DBAL/Driver/ResultStatement.php

The bottom line here is that either (1) the Zend PHP runtime doesn't care if all of the interfaces of a method are implemented (2) possible parameter conversion issues are occurring. An interesting point of note is that after trying to implement these interfaces correctly, HHVM could move beyond these fatals, but thre Zend PHP runtime would start to fatal.

Entities

Even after getting around the interface problems above, a new fatal arose:

``bash Doctrine\Tests\ORM\Functional\UnitOfWorkLifecycleTest::testMarkReadOnlyNonManaged Doctrine\ORM\Mapping\MappingException: No identifier/primary key specified for Entity "Doctrine\Tests\Models\CMS\CmsUser". Every Entity must have an identifier/primary key.


At this point, it was determined that more research was necessary. 


## Failures and Errors

After getting through the fatals, there were errors and failures in functionality.

### Timezone

This is not necessarily and error or failure, but HHVM does give this warning when running the Doctrine unit tests:

```bash
HipHop Strict Warning: It is not safe to rely on the system's timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected 'America/Los_Angeles' for 'PDT/-7.0/DST' instead in /data/users/joelm/php-open-source-projects/doctrine2/tests/Doctrine/Tests/ORM/Tools/EntityGeneratorTest.php on line 548

HHVM does not have an official php.ini file to set these timezones, so we need to get these variables set via a mechanism provided in the warning.

Call To Action

Determine what is going on with respect to the interface implementation fatal. That is the number one priority with respect to Doctrine.

Clone this wiki locally