PHPSpec 在 PHP7 中捕获类型错误

PHPSpec Catching TypeError in PHP7

我想在 PHP7 中测试带有标量类型提示和严格类型的示例方法。当我不传递参数时,该方法应该抛出 TypeError。 PHPSpec return 致命错误:

Uncaught TypeError: Argument 1 passed to Example::test

<?php

class Example
{
    public function test(string $name)
    {
        $this->name = $name;
    }
}


class ExampleSpec extends ObjectBehavior
{
    function it_is_initializable()
    {
        $this->shouldHaveType('Test\Example');
    }

    function it_check_test_method_when_not_pass_argument()
    {
        $this->shouldThrow('\TypeError')->during('test');
    }
}

开头我声明:declare(strict_types=1);

怎么了?如何测试投掷 TypeError

经进一步调查,这是一个 PHPSpec 错误,已被报告 here。这个错误几个月都没有修复,所以我建议对它发表评论。

如果您查看 src/PhpSpec/Matcher/ThrowMatcher.php 中的代码,您会发现 PHPSpec 捕获继承“Exception”的异常,然后检查该异常的实例类型。但是,TypeError 不是继承自 Exception,而是继承自 Error。它与 Exception 唯一的共同点是它们都实现了 Throwable 接口。

例如:

101     public function verifyPositive($callable, array $arguments, $exception = null)
102     {
103         try {
104             call_user_func_array($callable, $arguments);
105         } catch (\Exception $e) {
106             if (null === $exception) {
107                 return;
108             }
109
110             if (!$e instanceof $exception) {
111                 throw new FailureException(sprintf(
112                     'Expected exception of class %s, but got %s.',
113                     $this->presenter->presentValue($exception),
114                     $this->presenter->presentValue($e)
115                 ));
116             }

报告错误,解释这些细节,并向他们展示 this documentation 关于 TypeError.

的继承

对我来说,如果我用这个注释单元测试就可以了:

/**
 * @expectedException \TypeError
 */

那我的测试是绿色的