是否有可能PHPUnit Mock对象替换在类中创建的一个?

时间:2012-07-09 16:50:13

标签: php mocking phpunit

我一直在努力让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中加入一个,它将返回一个预先设置的样本数据数组,供该方法使用,而不是命中实际的数据库

1 个答案:

答案 0 :(得分:2)

是的,这是可能的。

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