捕获 ArgumentCountError 和 PHPUnit_Framework_Error_Warning

neu*_*ert 3 php phpunit unit-testing

有人提交pull请求我的一个库,其中一个参数作出更换像可选function doSomething($var)function doSomething($var = 'whatever')

因此,我添加了一个单元测试,以确保如果您没有将足够的变量传递给该方法,则会发出错误。为了抓住这一点,我使用了 PHPUnit 注释@expectedException。对于 PHP 7.0,预期的异常是,PHPUnit_Framework_Error_Warning但对于 PHP 7.1+,预期的异常是ArgumentCountError. 这提出了一个小问题。我可以让测试通过 PHP 7.0 及更早版本或通过 PHP 7.1 及更高版本。我不能让他们都支持。

另一个 PHPUnit 注释是,@requires但它似乎只允许您将测试限制为最低 PHP 版本 - 而不是最高 PHP 版本。例如。如果我这样做@requires PHP 7.1,则意味着 PHP 7.1 是运行测试所需的最低 PHP 版本,但无法使 PHP 7.0 成为运行测试的最高版本。

我认为这样做@expectedException Exception会起作用(因为大概PHPUnit_Framework_Error_Warning并且ArgumentCountError两者都扩展了 Exception 但似乎也不是这种情况。

如果我可以做类似的事情会很酷,@expectedException PHPUnit_Framework_Error_Warning|ArgumentCountError但 PHPUnit 文档中的任何内容都没有让我相信我可以并且https://github.com/sebastianbergmann/phpunit/issues/2216让它听起来像是无法完成时期。

也许我应该一起删除这个特定的单元测试?

Jak*_*las 5

您可以使用expectException()方法调用,而不是@expectedException注释。无论如何建议使用方法调用。

测试中的条件通常是一个坏主意,因为测试应该很简单,但如果你坚持,你可以实现以下内容:

public function testIt()
{
    if (PHP_VERSION_ID >= 70100) {
        $this->expectException(ArgumentCountError::class);
    } else {
        $this->expectException(PHPUnit_Framework_Error_Warning::class);
    }

    // ...
}
Run Code Online (Sandbox Code Playgroud)

您还可以实现两个单独的测试用例,并根据 PHP 版本跳过其中一个:

public function testItForPHP70()
{
    if (PHP_VERSION_ID >= 70100) {
        $this->markTestSkipped('PHPUnit_Framework_Error_Warning exception is thrown for legacy PHP versions only');
    }

    $this->expectException(PHPUnit_Framework_Error_Warning::class);

    // ...
}

public function testItForPHP71AndUp()
{
    if (PHP_VERSION_ID < 70100) {
        $this->markTestSkipped('ArgumentCountError exception is thrown for latest PHP versions only');
    }

    $this->expectException(ArgumentCountError::class);

    // ...
}
Run Code Online (Sandbox Code Playgroud)