doumo3903 2015-06-23 21:09
浏览 51
已采纳

PHPUnit与抽象类使用特征

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条回答 默认 最新

  • dongxiezhi9564 2015-06-25 16:24
    关注

    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

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀