捕获ArgumentCountError和PHPUnit_Framework_Error_Warning

时间:2018-01-10 14:23:21

标签: php unit-testing phpunit

有人向我的图书馆提交了拉取请求,其中通过将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_WarningArgumentCountError都会延伸Exception,但似乎也不是这样。

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

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

1 个答案:

答案 0 :(得分:3)

您可以使用expectException()方法调用,而不是@expectedException注释。使用方法调用is recommended anyway

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

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

    // ...
}

您还可以实现两个单独的测试用例,并根据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);

    // ...
}