3

可能重复:
PHP - 覆盖现有函数

我想使用模拟对我的一些具有外部依赖项的函数进行单元测试。

所以这里是......下面是我正在使用的简化模型。我继承的很多代码都是这样写的,所以我希望能够编写一些简单的测试,而不必尽可能重写:

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;
}

我的函数调用的代码没有包装在对象中,因此我无法将各种示例付诸实践,因为互联网上 99% 的示例都是基于面向对象的代码。甚至可以直接从 PHPunit 模拟程序函数吗?

我希望能够模拟call_some_function_that_runs_a_database_query返回的任何内容。我尝试过使用内置的 PHPunit 模拟方法,但这样做不会覆盖我函数中原始调用的结果。

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

4

1 回答 1

3

您可以使用runkit PHP 扩展将一个函数替换为在测试期间返回所需内容的函数。它比模拟对象更麻烦,因为在所有情况下(通过、失败、错误)测试后,您必须注意将原始对象换回。

被测功能

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);
    }
}
于 2012-10-25T01:37:40.303 回答