【问题标题】:Is it Possible to PHPUnit Mock Object to Replace one Created in Class?PHPUnit 模拟对象是否可以替换在类中创建的对象?
【发布时间】:2012-07-09 16:50:13
【问题描述】:

我一直在尝试让 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 的双倍,它将返回一个预设的样本数据数组供该方法使用,而不是访问实际数据库

【问题讨论】:

    标签: php mocking phpunit


    【解决方案1】:

    是的,这是可能的。

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

    【讨论】:

    • 如果对该数据以及 loadData 方法的一部分进行操作,这仍然有效吗?我意识到我可以用存根替换方法,但我认为这会覆盖内容并阻止我测试这些方法。或者我是否需要拆分方法,以便将查询对象的创建与方法的其余部分分开,并为此创建一个存根,返回查询的测试结果?
    • 添加了一段额外的代码来概述这些方法除了创建查询对象并返回查询结果数组之外的操作之一
    • “是的,这是可能的。”不打针怎么办?
    • @dok:通过创建从要测试的类扩展的存根类。一个常见的测试存根。
    猜你喜欢
    • 2013-04-27
    • 2021-10-31
    • 1970-01-01
    • 2016-03-24
    • 1970-01-01
    • 2021-08-18
    • 1970-01-01
    • 2017-04-07
    • 2018-08-19
    相关资源
    最近更新 更多