php - 是否可以模拟 PHPUnit 中不存在的函数?

标签 php mocking phpunit

我有一个单元测试,用于检查如果未安装 openssl_random_pseudo_bytes 是否会引发异常。但是,如果它已安装,则当前将跳过它。不过,这对我来说并不令人满意,因为它会导致不完美的测试运行。我可以设置单元测试通过,但这感觉像是作弊。

有没有人有什么想法?

这是我目前的测试:

public function testGenerateOpenSSLThrowsExceptionWhenFunctionDoesNotExist()
{
    if (function_exists('openssl_random_pseudo_bytes')) {
        $this->markTestSkipped('Cannot run test: openssl_random_pseudo_bytes function exists.');
    }

    $this->_salt->generateFromOpenSSL();
}

最佳答案

不是直接的,但是您可以使用 Can I "Mock" time in PHPUnit? 中描述的小技巧模拟 function_exists

先决条件

  • 被测类 (CUT) 在 PHP 命名空间中
  • function_exists() 以非限定名称调用(即不是 \function_exists())

例子

假设 CUT 看起来像这样:

namespace Stack;
class Salt
{
    ...
        if (function_exists('openssl_random_pseudo_bytes'))
    ...
}

那么这是你的测试,在同一个命名空间中:

namespace Stack;

function function_exists($function)
{
    if ($function === 'openssl_random_pseudo_bytes') {
        return SaltTest::$opensslExists;
    }
    return \function_exists($function);
}

class SaltTest extends \PHPUnit_Framework_Test_Case
{
    public static $opensslExists = true;

    protected function setUp()
    {
        self::$opensslExists = true;
    }

    public function testGenerateOpenSSLThrowsExceptionWhenFunctionDoesNotExist()
    {
        self::$opensslExists = false;
        $this->_salt->generateFromOpenSSL();
    }

}

命名空间函数将优先于核心函数并将所有参数委托(delegate)给核心函数,“openssl_random_pseudo_bytes”除外。

如果您的测试位于不同的命名空间中,您可以像这样为每个文件定义多个命名空间:

namespace Stack
{
    function function_exists($function)
    ...
}
namespace StackTest
{
    class SaltTest extends \PHPUnit_Framework_Test_Case
    ...
}

关于php - 是否可以模拟 PHPUnit 中不存在的函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32007032/

相关文章:

formatting - phpunit - 如何格式化输出

python-3.x - 如何模拟 googleapiclient.discovery.build 以单元测试从谷歌表格读取

unit-testing - 如何比较/匹配模拟中的闭包?

php - 双环 TWIG

php静态属性

ruby-on-rails - 如何取消 Mocha 模拟?

PHPUnit 在 Symfony 中单独测试

phpunit - 未找到 PHPUnit\Framework\ExpectationFailedException 类

php - 计算多个表中不同值的出现次数

php - Spotify API 未提供 token