我正在尝试使用 PHPUnit 编写一组单元测试(DISCALIMER:这是我尝试使用单元测试来提高代码质量的第一个项目)。
我目前有一个 ConnectionManager
类,用于管理与 MySQL 数据库的连接。该类有两个成员函数:
GetDBSetLinks
和 ConnectWithMysqli
。
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/