自定义PhpSpec匹配器和/或扩展名不起作用

时间:2019-03-21 14:16:59

标签: php phpspec

我正在尝试测试一门课程是否为最终课程。由于我尚未找到用于此目的的默认匹配器(或任何其他干净的测试方式),因此我决定创建一个自定义扩展,添加一个新的匹配器来执行此操作,但我无法使其正常工作。< / p>

我已经用内联匹配器尝试过,就像这样:

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.,而不是我想显示的消息。

另一个问题是我不想只上一堂课。这就是为什么我决定对此进行扩展。

这就是我得到的:

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()方法并返回true,则它对$this->shouldBeFinal();传递而对$this->shouldNotBeFinal();失败,但是我不接受要添加该方法。我应该没有它就工作,而且据我所知它应该能够那样工作,对吧?

我还尝试将自定义西装添加到我的 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 < / strong>,因为我没有从任何var_dump(…);

获得任何输出

我遵循了来自symfonycasts,phpspec文档本身以及其他一些github项目的教程和示例,它们几乎都与我的代码相同(除了名称空间,目录结构和类似的东西),所以我很客气在这里茫然。

如何使它成功调用$this->shouldBeFinal();$this->shouldNotBeFinal();

非常感谢whovere可以在这里帮助我。

P.S .:我也将此issue发布在phpspec的github上。

1 个答案:

答案 0 :(得分:0)

因此,显然优先级太低(请参阅this comment我的phpspec的github问题)。 PhpSpec \ Matcher \ IdentityMatcher shouldBe的来源)从 PhpSpec \ Matcher \ BasicMatcher 延伸,其中优先级设置为100。 因为我的设置为0,所以它首先要挖掘(我认为),因此执行不正确。我已将优先级设置为101,并且它可以正常工作(除非我发现肯定和否定的消息都已切换,否则我会发现)。