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


Bypassing mysqli_connect() error to write unit test

我正在尝试使用 PHPUnit 编写一组单元测试(DISCALIMER:这是我第一个尝试使用单元测试来提高代码质量的项目(。

我目前有一个ConnectionManager类,用于管理与MySQL数据库的连接。此类有两个成员函数: GetDBSetLinksConnectWithMysqli.

GetDBSetLinks是一个函数,它接收多个mysql数据库的连接信息数组(每个元素都包含主机名,用户名等和其他一些信息(,并将此信息传递到ConnectWithMysqli

ConnectWithMySqli()计算程序应该使用哪个重载的mysqli_connect()函数来连接MySQL数据库,然后使用传入的参数调用该重载。

当我使用我的单元测试将错误的连接信息(例如错误的密码(传递到GetDBSetLinks()时,错误信息得到了正确的处理,并按预期进入ConnectWithMySqli函数。当错误信息命中mysqli_connect()时,函数失败并触发预期的

mysql_connect((: 用户"root"@'192.168.1.113' (使用密码:YES("错误,访问被拒绝。

问题是这也终止了ConnectWithMySqli()的执行,因此ConnectWithMysqli()不会完成并返回我试图测试的变量。

我想做的是保持程序运行,但触发可以处理的异常。

问题是我刚刚开始使用try-catch,我不确定这样做的最佳方法。有人有什么想法吗?

连接.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;
}  

连接模块测试.php

<?php
require_once 'C:'Users'bsnider'Documents'BrandonDepot'SourceControl'git'repos'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(){
    }
}

我认为您应该尝试将所有可能的错误转换为异常,以便您可以根据需要使用 try/catch。

此列表中的第一个库可以帮助您做到这一点。