PhpUnit模拟内置函数

Tha*_*ung 5 php phpunit mocking

有没有一种方法来模拟/重写一个内置的功能shell_execPHPUnit.我知道Mockery并且我不能使用除了之外的其他库PHPUnit.我已经尝试了超过3小时而且某个地方卡住了.任何指针/链接都将受到高度赞赏.我在用Zend-framework2

Wil*_*ilt 8

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

检查这篇伟大的博客文章:PHP:"Mocking"内置函数,如单元测试中的time().

<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
        //...
    }
}
Run Code Online (Sandbox Code Playgroud)

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


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

  • 您的方法仅在您的测试脚本和实际脚本位于同一命名空间中时才有效。我的位于不同的命名空间中。 (2认同)

Ale*_*ker 7

非同质命名空间的答案;

正如@notnotundefined 指出的那样,这里的解决方案取决于与被测试代码位于同一命名空间中的测试。以下是如何使用竞争命名空间完成相同的测试。

<?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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)