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

标签 php mysql unit-testing exception try-catch

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

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

GetDBSetLinks 是一个函数,它接收多个 mysql 数据库的连接信息数组(每个元素包含主机名、用户名等以及其他一些信息),并将这些信息传递给 ConnectWithMysqli

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

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

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

问题是,这也会终止 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;
}  

ConnectionModuleTest.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。

this list中的第一个库可以帮助您做到这一点。

关于php - 绕过 mysqli_connect() 错误编写单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35089244/

相关文章:

php - 我怎样才能建立统计 map ?

Android:在仪器测试用例中创建目录

xcode - 如何在不阻塞主线程的情况下在 Xcode、单元测试中执行延迟?

php - MySql 查询优化以避免文件排序

PHP 包管理器

php - Laravel:按属性从集合中获取对象

javascript - ECMAScript 5 支持测试套件

php - Magento getUrlPath() 不起作用

php 文件不接受 css

mysql 5.7 geospatial 用于地理位置距离查询