我一直在尝试让PHPUnit模拟对象适用于我正在处理的一些遗留代码,但是我遇到了问题,因为我想要的对象是sub-in而且我很确定它必须是因为我用错了.
目前我们有一个纯粹用于创建查询的类,当另一个类想要创建查询时,它会创建该类的对象并将其传递给sql和数据库详细信息.我想要做的是让PHPUnit用我可以测试的模拟版本替换这个对象.
我发现的是,如果我在测试脚本中创建模拟对象,那么被测试的方法就会绕过它.我猜这是因为该方法正在创建然后在本地使用该对象而不是作为参数传递(在这种情况下,我可以使用作为参数传递的模拟对象来引用该方法).下面是代码可能如下所示的示例:
class SampleClass{
function loadData(){
$sql = "SELECT * FROM users";
$query = new Query();
$query->query($sql);
while($row = $query->get_row()){
if($row['email'] = ''){
$this->errors[] = "Email missing from user ".$row['user_id'];
}
$result[] = $query->get_row();
}
$this->users = $result;
if(count($user->errors) >= 1){
return $user->errors;
}else{
return true;
}
}
}
class Query{
function query($sql){
$this->result = mysql_query($sql);
}
function get_row(){
return mysql_fetch_assoc($this->result);
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在PHPUnit测试文件中创建一个模拟对象,它将用一个模拟对象替换SampleClass中的$ query对象,我可以用它来测试传递给的参数并控制响应?我将无法替换查询类或更改它的引用方式,因为它在我们的应用程序中广泛使用,但我希望至少能够为它创建某种形式的测试框架.非常感谢您能给予的任何帮助
编辑说明不仅仅是在loadData方法中发生的查询,这是我试图测试的方法的一部分.我希望在查询类方法get_row中加入一个子类,它将返回一个预先设置的样本数据数组,供该方法使用而不是命中实际的数据库
我一直在努力让我们的系统与PHPUnit更加兼容,所以我们可以对我们的类进行更多的单元测试,并设法让它们中的一些使用模拟对象,但我遇到了一个我看不出的问题到处走走
我们拥有的一个类(我正在创建一个模拟版本)用于查询.您将查询字符串传递给它的"query()"方法,它会记录查询,运行它并返回结果.它还使用名为"get_row()"的方法包装mysql_fetch_assoc,该方法返回与原始数据类似的数组值.
问题在于,在某些方法中,有多个查询被传递给"query()"方法,因此需要运行多个while循环以将数据加载到不同的变量中.我在下面创建了一个简化版本:
class object{
public function __construct($query){
$this->query = $query;
}
public function loadData(){
$data1 = queryDataSource("SELECT * FROM data1");
$data2 = queryDataSource("SELECT * FROM data2");
return Array(
"data1" => $data1,
"data2" => $data2,
);
}
private function queryDataSource($query){
$this->query->query($query)
while($row = $this->query->get_row()){
$result[] = $row;
}
return $result
}
}
class testObject extends PHPUnit_Framework_TestCase{
method testLoadData(){
$test_data = Array('name' => 'Bob', 'number' => '98210');
$query = $this->getMock('Query');
$query->expects($this->any())->method('query');
$query->expects($this->at(1))->method('get_row')->will($this->returnValue($test_data);
$query->expects($this->at(2))->method('get_row')->will($this->returnValue(False);
$query->expects($this->at(3))->method('get_row')->will($this->returnValue($test_data);
$query->expects($this->at(4))->method('get_row')->will($this->returnValue(False);
}
}
Run Code Online (Sandbox Code Playgroud)
为了逃避$ object-> queryDataSource()中的第一个while循环,我返回一个布尔FALSE值,就像执行mysql_fetch_assoc时一样.问题是,当它试图运行第二个查询并通过get_row()获取数据时,模拟对象似乎继续返回FALSE ratehr而不是继续到at(3)点.即使有4个对象也会发生这种情况,只有第一个会将测试数据作为返回值,然后第二次得到FALSE,其他的每次都会得到FALSE. …