自定义 PhpSpec 匹配器 and/or 扩展无效
Custom PhpSpec matcher and/or extension not working
我正在尝试测试 class 是否是最终的。由于我还没有找到默认的匹配器(或任何其他测试它的干净方法),我决定创建一个自定义扩展,添加一个新的匹配器来做到这一点,但我无法让它工作。
我已经用内联匹配器试过了,像这样:
public function getMatchers(): array
{
return [
'beFinal' => function ($subject) {
$reflection = new \ReflectionClass($subject);
if (!$reflection->isFinal()) {
throw new FailureException('Expected subject to be final, but it is not.');
}
return true;
},
];
}
这在我调用 $this->shouldBeFinal();
时效果很好。问题是,当我调用 $this->shouldNotBeFinal();
时,它会输出一条通用消息:[obj:Class\To\Test] not expected to beFinal(), but it did.
,而不是我想显示的消息。
另一个问题是我不希望只有一个 class。这就是我决定对其进行扩展的原因。
这是我得到的:
phpspec.yml:
extensions:
PhpSpecMatchers\Extension: ~
PhpSpecMatchers/Extension.php:
<?php
declare(strict_types=1);
namespace PhpSpecMatchers;
use PhpSpec\ServiceContainer;
use PhpSpecMatchers\Matchers\BeFinalMatcher;
class Extension implements \PhpSpec\Extension
{
public function load(ServiceContainer $container, array $params): void
{
$container->define(
'php_spec_matchers.matchers.be_final',
function ($c) {
return new BeFinalMatcher();
},
['matchers']
);
}
}
PhpSpecMatchers/Matchers/BeFinalMatcher.php:
<?php
declare(strict_types=1);
namespace PhpSpecMatchers\Matchers;
use PhpSpec\Exception\Example\FailureException;
use PhpSpec\Matcher\BasicMatcher;
class BeFinalMatcher extends BasicMatcher
{
public function supports(string $name, $subject, array $arguments): bool
{
return $name === 'beFinal';
}
public function getPriority(): int
{
return 0;
}
protected function matches($subject, array $arguments): bool
{
$reflection = new \ReflectionClass($subject);
return $reflection->isFinal();
}
protected function getFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException('Expected subject to not be final, but it is.');
}
protected function getNegativeFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException('Expected subject to be final, but it is not.');
}
}
每当我尝试使用此配置调用 $this->beFinal();
时,规范就会被破坏并显示以下消息:method [array:2] not found.
。例如,如果我将 isFinal() 方法添加到我正在测试的 class 并且 return 为真,它会通过 $this->shouldBeFinal();
而失败$this->shouldNotBeFinal();
,但我不想添加该方法。我应该在没有它的情况下工作,据我所知,它应该能够像那样工作,对吗?
我还尝试将自定义 suites 添加到我的 phpspec.yml,如下所示:
suites:
matchers:
namespace: PhpSpecMatchers\Matchers
psr4_prefix: PhpSpecMatchers\Matchers
src_path: src/PhpSpecMatchers/Matchers
spec_prefix: spec/PhpSpecMathcers/Matchers
但这并没有改变任何事情。我还尝试将以下配置添加到 phpspec.yml:
extensions:
PhpSpecMatchers\Extension:
php_spec_matchers:
src_path: src
spec_path: spec
这也没有改变任何东西。
我尝试过的另一件事是放弃扩展方法,只在 phpspec.yml 中声明我的数学,就像这样:
matchers:
- PhpSpecMatchers\Matchers\BeFinalMatcher
如您所料:结果相同。
确实调用了 PhpSpecMatchers\Extension 中的加载(通过简单的 var_dump(…);
测试),但它似乎没有在 PhpSpecMatchers\Matchers\BeFinalMatcher,因为我没有从任何 var_dump(…);
得到任何输出
我遵循了 symfonycasts、phpspec 文档本身和我发现的其他一些 github 项目的教程和示例,它们几乎与我的代码相同(除了命名空间、目录结构诸如此类),所以我有点不知所措。
如何才能成功调用 $this->shouldBeFinal();
和 $this->shouldNotBeFinal();
?
非常感谢能帮助我的人。
P.S.: 我也在 phpspec 的 github.
上发布了这个 issue
显然优先级太低(参见 this comment 我的 phpspec 的 github 问题)。 PhpSpec\Matcher\IdentityMatcher(shouldBe
的来源)从优先级设置为 100 的 PhpSpec\Matcher\BasicMatcher 延伸.
由于我的设置为 0,它首先被我的(我认为)因此没有正确执行。我已将我的优先级设置为 101,它完美地工作(除了我切换了正面和负面消息,我发现了)。
我正在尝试测试 class 是否是最终的。由于我还没有找到默认的匹配器(或任何其他测试它的干净方法),我决定创建一个自定义扩展,添加一个新的匹配器来做到这一点,但我无法让它工作。
我已经用内联匹配器试过了,像这样:
public function getMatchers(): array
{
return [
'beFinal' => function ($subject) {
$reflection = new \ReflectionClass($subject);
if (!$reflection->isFinal()) {
throw new FailureException('Expected subject to be final, but it is not.');
}
return true;
},
];
}
这在我调用 $this->shouldBeFinal();
时效果很好。问题是,当我调用 $this->shouldNotBeFinal();
时,它会输出一条通用消息:[obj:Class\To\Test] not expected to beFinal(), but it did.
,而不是我想显示的消息。
另一个问题是我不希望只有一个 class。这就是我决定对其进行扩展的原因。
这是我得到的:
phpspec.yml:
extensions:
PhpSpecMatchers\Extension: ~
PhpSpecMatchers/Extension.php:
<?php
declare(strict_types=1);
namespace PhpSpecMatchers;
use PhpSpec\ServiceContainer;
use PhpSpecMatchers\Matchers\BeFinalMatcher;
class Extension implements \PhpSpec\Extension
{
public function load(ServiceContainer $container, array $params): void
{
$container->define(
'php_spec_matchers.matchers.be_final',
function ($c) {
return new BeFinalMatcher();
},
['matchers']
);
}
}
PhpSpecMatchers/Matchers/BeFinalMatcher.php:
<?php
declare(strict_types=1);
namespace PhpSpecMatchers\Matchers;
use PhpSpec\Exception\Example\FailureException;
use PhpSpec\Matcher\BasicMatcher;
class BeFinalMatcher extends BasicMatcher
{
public function supports(string $name, $subject, array $arguments): bool
{
return $name === 'beFinal';
}
public function getPriority(): int
{
return 0;
}
protected function matches($subject, array $arguments): bool
{
$reflection = new \ReflectionClass($subject);
return $reflection->isFinal();
}
protected function getFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException('Expected subject to not be final, but it is.');
}
protected function getNegativeFailureException(string $name, $subject, array $arguments): FailureException
{
return new FailureException('Expected subject to be final, but it is not.');
}
}
每当我尝试使用此配置调用 $this->beFinal();
时,规范就会被破坏并显示以下消息:method [array:2] not found.
。例如,如果我将 isFinal() 方法添加到我正在测试的 class 并且 return 为真,它会通过 $this->shouldBeFinal();
而失败$this->shouldNotBeFinal();
,但我不想添加该方法。我应该在没有它的情况下工作,据我所知,它应该能够像那样工作,对吗?
我还尝试将自定义 suites 添加到我的 phpspec.yml,如下所示:
suites:
matchers:
namespace: PhpSpecMatchers\Matchers
psr4_prefix: PhpSpecMatchers\Matchers
src_path: src/PhpSpecMatchers/Matchers
spec_prefix: spec/PhpSpecMathcers/Matchers
但这并没有改变任何事情。我还尝试将以下配置添加到 phpspec.yml:
extensions:
PhpSpecMatchers\Extension:
php_spec_matchers:
src_path: src
spec_path: spec
这也没有改变任何东西。
我尝试过的另一件事是放弃扩展方法,只在 phpspec.yml 中声明我的数学,就像这样:
matchers:
- PhpSpecMatchers\Matchers\BeFinalMatcher
如您所料:结果相同。
确实调用了 PhpSpecMatchers\Extension 中的加载(通过简单的 var_dump(…);
测试),但它似乎没有在 PhpSpecMatchers\Matchers\BeFinalMatcher,因为我没有从任何 var_dump(…);
我遵循了 symfonycasts、phpspec 文档本身和我发现的其他一些 github 项目的教程和示例,它们几乎与我的代码相同(除了命名空间、目录结构诸如此类),所以我有点不知所措。
如何才能成功调用 $this->shouldBeFinal();
和 $this->shouldNotBeFinal();
?
非常感谢能帮助我的人。
P.S.: 我也在 phpspec 的 github.
上发布了这个 issue显然优先级太低(参见 this comment 我的 phpspec 的 github 问题)。 PhpSpec\Matcher\IdentityMatcher(shouldBe
的来源)从优先级设置为 100 的 PhpSpec\Matcher\BasicMatcher 延伸.
由于我的设置为 0,它首先被我的(我认为)因此没有正确执行。我已将我的优先级设置为 101,它完美地工作(除了我切换了正面和负面消息,我发现了)。