Php 是否可以对过程(非oo)函数使用模拟?

Php 是否可以对过程(非oo)函数使用模拟?,php,unit-testing,mocking,phpunit,Php,Unit Testing,Mocking,Phpunit,可能重复: 我想使用mocking对一些具有外部依赖性的函数进行单元测试 所以这里是。。。下面是我正在使用的简化模型。我继承的许多代码都是以这种方式编写的,因此,如果可能的话,我希望能够编写一些简单的测试,而不必重写: function display_tasks($id) { $tasks = call_some_function_that_runs_a_database_query($id); $html = "<some html>"; forea

可能重复:

我想使用mocking对一些具有外部依赖性的函数进行单元测试

所以这里是。。。下面是我正在使用的简化模型。我继承的许多代码都是以这种方式编写的,因此,如果可能的话,我希望能够编写一些简单的测试,而不必重写:

function display_tasks($id)
{
    $tasks = call_some_function_that_runs_a_database_query($id);

    $html = "<some html>";

    foreach ($tasks as $task)
    {
        // Some operations here
    }

    $html .= "</some html>";

    return $html;
}
功能显示任务($id)
{
$tasks=调用运行数据库查询的函数($id);
$html=“”;
foreach($tasks作为$task)
{
//这里有些行动
}
$html.=”;
返回$html;
}
我的函数调用的代码没有包装在对象中,因此我很难将各种示例付诸实践,因为internet上99%的示例都基于面向对象的代码。甚至可以直接从PHPunit模拟过程函数吗

我希望能够模拟任何
调用\u运行的\u函数\u数据库\u查询
返回的函数。我尝试过使用内置的PHPunit mocking方法,但这样做不会覆盖函数中原始调用的结果

任何帮助或示例都将不胜感激。

您可以使用替换函数,以在测试期间返回所需的函数。这比模拟对象更麻烦,因为在所有情况下(通过、失败、错误),测试结束后都必须小心地将原始对象交换回来

正在测试的功能

function getTasksFromDatabase($id) {
    // call to database...
}
测试用例

function stub_getTasksFromDatabase($id) {
    return array('one', 'two', 'three');
}

class getUserTest extends PHPUnit_Framework_TestCase {
    public static function setUpBeforeClass() {
        runkit_function_rename('getTasksFromDatabase', 'orig_getTasksFromDatabase');
        runkit_function_rename('stub_getTasksFromDatabase', 'getTasksFromDatabase');
    }

    public function tearDownAfterClass() {
        runkit_function_rename('getTasksFromDatabase', 'stub_getTasksFromDatabase');
        runkit_function_rename('orig_getTasksFromDatabase', 'getTasksFromDatabase');
    }

    public function setUp() {
        $html = getTasks(1);
        self::assertEquals('<some html>...one...two...three...</some html>', $html);
    }
}
函数存根\u getTasksFromDatabase($id){
返回数组('1','2','3');
}
类getUserTest扩展了PHPUnit\u框架\u测试用例{
公共静态函数setUpBeforeClass(){
runkit_函数_rename('getTasksFromDatabase','orig_getTasksFromDatabase');
runkit_函数_rename('stub_getTasksFromDatabase','getTasksFromDatabase');
}
公共函数tearDownAfterClass(){
runkit_函数_rename('getTasksFromDatabase','stub_getTasksFromDatabase');
runkit_函数_rename('orig_getTasksFromDatabase','getTasksFromDatabase');
}
公共功能设置(){
$html=getTasks(1);
self::assertEquals(“…一…二…三…”,$html);
}
}

谢谢,大卫。事实上,我昨晚很晚才发现这个解决方案,但我没有安装runkit,而是安装了php测试助手(也是伟大的Sebastian Bergmann编写的)。详情如下: