php - PHPUnit 模拟对象是否可以替换类中创建的对象?

标签 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 的两倍中进行子查询,它将返回一个预先设置的示例数据数组供该方法使用,而不是它命中一个实际的数据库

最佳答案

是的,这是可能的。

但是,您可以只创建自己的 SampleClass stub 。您也可以使 Query 的类名或实例成为依赖项。所以你实际上可以注入(inject)它。我会说这是一种更好的方法,而且对您来说编写测试要容易得多。

关于php - PHPUnit 模拟对象是否可以替换类中创建的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11399600/

相关文章:

phpunit 和 symfony2 : how to assert number of queries from client or response?

php - 在 phpunit 中模拟请求

php - 使用查询 (SQL) 从所有三个表获取数据

php - 使用 PDO 创建长插入 SQL 查询的最佳方式

ios - 如何使用 OCMockito stub 类方法?

PHPUnit 无法加载带有命名空间语句的文件

php - 我如何限制对页面的访问?

Php mysql插入同一表id的数组键值

javascript - 如何使用 Wolfpack.js 测试 Sails.js 模型的独特电子邮件属性?

c# - 干净地验证传递给 Mock 的参数的许多属性 [单独在单个验证调用之外]?