6

我一直在尝试让 PHPUnit 模拟对象为我正在处理的一些遗留代码工作,但是我在让它代替我所追求的对象时遇到了问题,我很确定这一定是因为我用错了。

目前我们有一个纯粹用于创建查询的类,当另一个类想要进行查询时,它会创建该类的一个对象并将 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);
    }
}

有没有办法在 PHPUnit 测试文件中创建一个模拟对象,它将 SampleClass 中的 $query 对象替换为一个模拟对象,我可以用它来测试传递给的参数并控制其响应?我将无法替换查询类或更改它的引用方式,因为它在我们的应用程序中被广泛使用,但我希望至少能够为它创建某种形式的测试框架。感谢您提供的任何帮助

编辑以澄清在 loadData 方法中发生的不仅仅是查询,这是我正在尝试测试的方法的一部分。我希望在查询类方法 get_row 中加入一个双倍的查询类方法,它将返回一个预设的样本数据数组以供该方法使用,而不是访问实际的数据库

4

1 回答 1

2

是的,这是可能的。

但是,您可以只创建SampleClass自己的存根。Query您也可以创建依赖项的类名或实例。所以你实际上可以注入它。我会说这是一种更好的方法,并且更容易让您编写测试。

于 2012-07-09T16:55:38.900 回答