du13932014807 2016-01-29 16:23
浏览 60
已采纳

绕过mysqli_connect()错误来编写单元测试

I'm trying to write a set of unit tests using PHPUnit (DISCALIMER: This is my first project attempting to use unit tests for improving code quality).

I'm currently have the a ConnectionManager class which is managing the connection to the MySQL databases. This class has two member functions: GetDBSetLinks and ConnectWithMysqli.

GetDBSetLinks is a function that takes in an array of connection information for multiple mysql databases (each element contains Hostname, Username, etc. and some other info), and passes this information into ConnectWithMysqli.

ConnectWithMySqli() calculates which overload of the mysqli_connect() function the program should use to connect the the MySQL database and then calls that overload using the passed in parameters.

When I pass bad connection information (such as a bad password) into GetDBSetLinks() using my unit test, the bad information is handled properly makes it to the ConnectWithMySqli function as expected. When the bad information hits mysqli_connect(), the function fails and triggers the expected

mysql_connect(): Access denied for user 'root'@'192.168.1.113' (using password:YES)" error.

The problem is that this also terminates execution of ConnectWithMySqli(), thus ConnectWithMysqli() will not complete and return the variable that I am trying to test against.

What I would like to do is to keep the program running but trigger an exception that can be handled.

Problem is I just started using try-catch and I'm not really sure the best way to do this. Anyone have any ideas?

Connection.php

<?php

class FailedConnection extends Exception{}

class ConnectionManager {
    //FUNCTION: Gets List of Database Links for given database set----------------//
    static public function GetDBSetLinks($CurrentDBSet){
        $DatabaseLinkList = array();

        foreach ($CurrentDBSet as $DatabaseInfoString){
            //Split the Database info string by commas. The input string found in the
            //configuration file is a single string containing all of the parameters
            //needed to connect to the SQL database. The statement below takes this string
            //and converts it into three separate variables, so that they can be passed into mysqli_connect()
            $SplitDBInfo = preg_split('/,/', $DatabaseInfoString);

            //Initialize a variable that serves as an iterator. This variable also holds
            //the number of arguments that were found in the config fie.
            $NumArgs = 0;

            //Initialize other variables necessary to connect to the current database.
            $DatabaseID = "NULL";
            $HostName = "NULL";
            $dbUsername = "NULL";
            $dbPassword = "NULL";
            $DatabaseName = "NULL"; //NOTE: Database name in the config file should exactly match the name of the database on the server.
            $PortNumber = "NULL";
            $Socket = "NULL";

            //Cycle through the individual params now stored in SplitDBInfo, (1.) count
            //them, then (2.) assign them to the appropriate variable to pass into mysqli_connect()
            foreach ($SplitDBInfo as $Parameter){
                $NumArgs ++; //(1.)              
                switch ($NumArgs) { //(2.)
                    case 1:
                        $DatabaseID = $Parameter;
                        break;
                    case 2:
                        $HostName = $Parameter;
                        break;
                    case 3:
                        $dbUsername = $Parameter;
                        break;
                    case 4:
                        $dbPassword = $Parameter;
                        break;
                    case 5:
                        $DatabaseName = $Parameter;
                        break;
                    case 6:
                        $PortNumber = $Parameter;
                        break;
                    case 7:
                        $Socket = $Parameter;
                        break;
                    default:
                        break;
                }
                //print $Parameter . "<br>"; //DEBUG
            }
            print '<br>' ."NumArgs: " . ($NumArgs) . '<br>'; //DEBUG ONLY
            print "Number of Function Arguments: " . ($NumArgs -1) . '<br>'; //DEBUG ONLY;
            echo "Connecting to Database '" . $DatabaseID . "' at hostname " . $HostName ."." . '<br>';

            $link = self::ConnectWithMysqli($NumArgs, $HostName, $dbUsername, $dbPassword, $DatabaseName, $PortNumber, $Socket);


            //If our link to the database is not successful, escape this sequence and do not put the link in our list of linked databases.
            if (!$link){
                echo "No Successful link to '" . $DatabaseID . "' at hostname " . $HostName .".";
                echo '<br>';
            }
            //Otherwise, our link should be good, and we should add it to our list of database links.
            else{
                echo "Connection to Database '" . $DatabaseID . "' at hostname " . $HostName ." was successful.";
                echo '<br>';
                array_push($DatabaseLinkList, $link);
            }    
        }
    //After we finish iterating to generate a list of viable links, we can use these
    //links to perform database operations.
    return $DatabaseLinkList;
    }

    function ConnectWithMysqli($NumArgs,$HostName, $dbUsername, $dbPassword, $DatabaseName, $PortNumber, $Socket){
        switch($NumArgs) {
            case 2:
                $link = mysqli_connect($HostName);
                //could not connect
                break;
            case 3:
                $link = mysqli_connect($HostName,$dbUsername);
                break;
            case 4:
                $link = mysql_connect($HostName,$dbUsername,$dbPassword);
                //$link = mysqli_connect($HostName,$dbUsername,$dbPassword);
                break;
            case 5:
                print ($DatabaseName);
                $link = mysqli_connect($HostName,$dbUsername,$dbPassword,$DatabaseName);
                break;
            case 6:
                $link =  mysqli_connect($HostName, $dbUsername, $dbPassword, $DatabaseName, $PortNumber, $Socket);
                break;
            default:
                throw new FailedConnection;
            }
    try{
        if(!$link){
            throw new FailedConnection;
        }
    }
    catch(FailedConnection $e){
        return "Null";
    }

return $link;
}  

ConnectionModuleTest.php

<?php
require_once 'C:\Users\bsnider\Documents\BrandonDepot\SourceControl\gitepos\GLS_DBSearchProject\Connection.php';

class ConnectionModuleTest extends PHPUnit_Framework_TestCase{
    public function setUp(){}
    public function tearDown(){}

    public function testDataGetDBSetLinks_GoodConnection(){
        $ConnectionManager = new ConnectionManager;
        //Valid Connection Parameters
        $DBSet = array('MainDatabase,192.168.1.41,root,colt45', 'MainDatabase,192.168.1.41,root,colt45');
        $Result = $ConnectionManager->GetDBSetLinks($DBSet); //$Result
        $this->assertNotEmpty($Result);
    }

    public function testDataGetDBSetLinks_BadHostName(){
        $ConnectionManager = new ConnectionManager;
        //Invalid Connection Parameters
        $DBSet = array('MainDatabase,192.168.1.20,root,colt45', 'MainDatabase,192.168.1.20,root,colt45');
        $Result = $ConnectionManager->GetDBSetLinks($DBSet); //$Result
        $this->assertEmpty($Result);
    }

    public function testDataGetDBSetLinks_BadPassword(){
        $ConnectionManager = new ConnectionManager;
        //Invalid Connection Parameters
        $DBSet = array('MainDatabase,192.168.1.41,root,badpassword', 'MainDatabase,192.168.1.41,root,badpassword');
        $Result = $ConnectionManager->GetDBSetLinks($DBSet); //$Result
        $this->assertEmpty($Result);        
        }
    public function testConnectWithMysqli(){

    }
}
  • 写回答

1条回答 默认 最新

  • dongqi3533 2016-01-29 16:55
    关注

    I think you should attempt to convert all possible errors into exceptions, so that you can use try/catch as you wish.

    The first library in this list can help you do that.

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

报告相同问题?

悬赏问题

  • ¥15 请问有人会紧聚焦相关的matlab知识嘛?
  • ¥15 网络通信安全解决方案
  • ¥50 yalmip+Gurobi
  • ¥20 win10修改放大文本以及缩放与布局后蓝屏无法正常进入桌面
  • ¥15 itunes恢复数据最后一步发生错误
  • ¥15 关于#windows#的问题:2024年5月15日的win11更新后资源管理器没有地址栏了顶部的地址栏和文件搜索都消失了
  • ¥100 H5网页如何调用微信扫一扫功能?
  • ¥15 讲解电路图,付费求解
  • ¥15 有偿请教计算电磁学的问题涉及到空间中时域UTD和FDTD算法结合的
  • ¥15 three.js添加后处理以后模型锯齿化严重