Я пытаюсь проверить, является ли класс окончательным. Поскольку я не нашел сопоставления по умолчанию для этого (или любого другого чистого способа его тестирования), я решил создать собственное расширение, которое добавляет новый сопоставитель для этого, но я не могу заставить его работать.
Я пробовал это с помощью встроенного сопоставителя, вот так:
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
Это тоже ничего не меняет.
Еще одна вещь, которую я попробовал, это отказаться от подхода расширения и просто объявить мой mather в phpspec.yml , вот так:
matchers:
- PhpSpecMatchers\Matchers\BeFinalMatcher
Как и следовало ожидать: те же результаты.
Загрузка в PhpSpecMatchers \ Extension действительно вызывается (проверяется простым var_dump(…);
), но кажется, что она ничего не достигает в PhpSpecMatchers \ Matchers \ BeFinalMatcher , так как я не получаю никакого вывода из любого var_dump(…);
Я следовал учебным пособиям и примерам из symfonycasts, самого phpspec docs и некоторых других проектов github, которые я обнаружил, все они почти идентичны моему коду (за исключением пространств имен, структур каталогов и тому подобного), поэтому я любезен в недоумении здесь.
Как мне добраться до точки, где я могу успешно позвонить $this->shouldBeFinal();
и $this->shouldNotBeFinal();
?
Большое спасибо, кто может помочь мне здесь.
P.S .: Я также опубликовал этот выпуск на github phpspec.