PhpUnit模拟内置函数

时间:2016-09-26 15:34:17

标签: php mocking phpunit

有没有办法在shell_exec中模拟/覆盖内置函数PHPUnit。我知道Mockery并且我不能使用除PHPUnit之外的其他库。我已经尝试了超过3小时,某个地方卡住了。任何指针/链接都将受到高度赞赏。 我正在使用Zend-framework2

4 个答案:

答案 0 :(得分:5)

有几种选择。例如,您可以在测试范围的命名空间中重新声明php函数shell_exec

请参阅这篇精彩的博文:PHP: “Mocking” built-in functions like time() in Unit Tests

<php
namespace My\Namespace;

/**
 * Override shell_exec() in current namespace for testing
 *
 * @return int
 */
function shell_exec()
{
    return // return your mock or whatever value you want to use for testing
}

class SomeClassTest extends \PHPUnit_Framework_TestCase
{ 
    /*
     * Test cases
     */
    public function testSomething()
    {
        shell_exec(); // returns your custom value only in this namespace
        //...
    }
}

现在,如果您在shell_exec中的某个类中使用了全局My\Namespace函数,那么它将使用您的自定义shell_exec函数。

您还可以将模拟函数放在另一个文件中(与SUT具有相同的命名空间)并将其包含在测试中。就像那样,如果测试具有不同的命名空间,你也可以模拟函数。

答案 1 :(得分:0)

您可以尝试使用badoo/soft-mocks包来模拟任何内置函数,包括public onUserRowSelect(event) { var selectedRows = event.selected; } 之类的自定义对象。 例如

Mockery

这真的很有用,尤其是对于依赖于外部资源的内置功能。例如:

  • curl_exec
  • get_dns_record

答案 2 :(得分:0)

非均匀名称空间的答案;

正如@Thabung指出的那样,此处的解决方案取决于与所测试代码位于相同命名空间中的测试。以下是如何使用竞争的名称空间完成相同的测试。

<php
namespace My\Namespace {
    /**
     * Override shell_exec() in the My\Namespace namespace when testing
     *
     * @return int
     */
    function shell_exec()
    {
        return // return your mock or whatever value you want to use for testing
    }
}

namespace My\Namespace\Tests {
    class SomeClassTest extends \PHPUnit_Framework_TestCase
    {
        public function testSomething()
        {
            // The above override will be used when calling shell_exec 
            // from My\Namespace\SomeClass::something() because the 
            // current namespace is searched before the global.
            // https://www.php.net/manual/en/language.namespaces.fallback.php
            (new SomeClass())->something();
        }
    }
}

答案 3 :(得分:0)

您不需要任何库或框架。

当然,您不希望将拐杖放在不可测试的代码下。您要做的是修复有缺陷的架构并使其可测试。

  1. 定义一个 ShellExecutorInterface
  2. 将接口注入客户端类。
  3. 在生产环境中提供带有 shell_exec() 的实现。
  4. 在测试环境中提供模拟实现。