1
votes

I have an abstract class DatabaseManager with quite some children like General_db_manager, Data_Importer, Translation_Manager, etc. which used to work properly. It is still working properly when I'm not running my unit test actually...

I just finished writing this ExceptionLogger class which required database connection, but I didn't want it to be a children of DataBaseManager since I'm planning to use it in DatabaseManager (and I want to avoid "diamond of death").

So I putted out some of DatabaseManager code in a traits like this:

trait ConnectionnHelper{


    protected static $support_user = "not_real_value";

    protected static $support_pass = "Not_real_value";

    protected static $whitelist = array('127.0.0.1.', "::1");


    /**
    * Return the host for a connection to our mysql server database.
    *
    * @return String
    */ 
    protected static function getMySqlHost() {

        $host = "";

        if (getenv('REMOTE_ADDR')) {

            if (in_array(getenv('REMOTE_ADDR'), self::$whitelist)) {

                $host = "127.0.0.1.";
            }
        }
        elseif (isset($_SERVER['REMOTE_ADDR'])) {

            if (in_array($_SERVER['REMOTE_ADDR'], self::$whitelist)) {

                $host = "127.0.0.1.";
            }
        }
        elseif(!getenv('REMOTE_ADDR') and !isset($_SERVER['REMOTE_ADDR'])) {

            $host = "127.0.0.1.";
        }

        return $host;   
    }
}

And I included my trait both in my DataBaseManager and my ExceptionLogger.

abstract class DataBaseManager {

    use ConnectionHelper;

When I remove the "use ConnectionnHelper", my unit test runs without error; but if I keep it, I receive result like this :

FILE : BACKUP_MANAGER_TEST.PHP

Fatal error: Class 'DataBaseManager' not found in C:\xampp\htdocs\general_controler\general_db_manager.php on line 14


FILE : GC_DATA_IMPORTER_TEST.PHP

Fatal error: Class 'DataBaseManager' not found in C:\xampp\htdocs\general_controler\general_db_manager.php on line 14

What bugs me is that my trait is doesn't require any class. So, I'm not so sure why it require my GeneralDBManager class which is also a children of DatabaseManager and is running without error

FILE : GENERAL_DB_MANAGER_TEST.PHP

PHPUnit 3.7.21 by Sebastian Bergmann.

.....

Time: 0 seconds, Memory: 2.75Mb

OK (5 tests, 22 assertions)

Here's my line 14 in GeneralDBManager (and the only require in the class):

require_once(realpath(dirname(__FILE__)) . '../database_manager.php');

class generalDbManager extends DataBaseManager{

No error neither in my ExceptionLogger:

FILE : EXCEPTION_LOGGER_TEST.PHP

PHPUnit 3.7.21 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 2.75Mb

OK (1 test, 2 assertions)

Is anyone already faced a similar problem?

Thank you,

Jonathan Parent-Lévesque

1

1 Answers

0
votes

here's solution to my problem for those who are interested.

First I tried to add an abstract class connection_manager which would be the parent of both to exception_logger and database_manager (this is probably a better design than using trait anyway...)

Yet, I still had the same problem:

FILE : BACKUP_MANAGER_TEST.PHP

Fatal error: Class 'DataBaseManager' not found in C:\xampp\htdocs\general_controler\general_db_manager.php on line 14

As it seems, there's some kind of circular requirement that PHP seems to be able to deal with, but not PHPunit.

To visualize my solution, let's suppose you got a test class like this one:

require_once(realpath(dirname(__FILE__)) . '/../backup_manager.php');

class BackupManagerTest extends phpunit_framework_testcase {

    public function setUp(){}

    public function tearDown(){}

    public function testGetBackupMode(){

        //test 1
        $myTag = BackupManager::getBackupMode("test");

        $this->assertNotEmpty($myTag);

        $this->assertContains('type="radio"', $myTag);

        $this->assertContains('value="1"', $myTag);

        $this->assertContains('value="2"', $myTag);

        $this->assertContains('id="1_RADIO" name="test" checked', $myTag);

        //test 2
        $myTag = BackupManager::getBackupMode("woot", BackupMode::BACKUP_SELECTED);

        $this->assertNotEmpty($myTag);

        $this->assertContains('id="2_RADIO" name="woot" checked', $myTag);


        //test 3
        $myTag = BackupManager::getBackupMode("blu", -10);

        $this->assertNotEmpty($myTag);

        $this->assertContains('id="1_RADIO" name="blu" checked', $myTag);
    }
}

I was able to solve the problem by adding an require for the general_db_manager that causes the problem right before the require for the classes having problems in their test files. By example:

require_once(realpath(dirname(__FILE__)) . '/../../../general_controler/general_db_manager.php');
require_once(realpath(dirname(__FILE__)) . '/../backup_manager.php');

Et voilà, my magic charm is working!

FILE : BACKUP_MANAGER_TEST.PHP

PHPUnit 3.7.21 by Sebastian Bergmann.

.

Time: 0 seconds, Memory: 2.00Mb

OK (1 test, 9 assertions)

Of course, this is not an excuse for not seeking for the very best class design, yet it should save some headache to some poor programmers in despair.

Have a nice day,

Jonathan Parent-Lévesque from Montreal