我正在使用PHPSpec进行测试,我在我的spec文件中有自定义匹配器,我不想在每个使用它们的文件中重复这些匹配。
我希望能够扩展PHPSpec的行为和/或我所有测试的行为,以使用一组全局的自定义匹配器。
PHPSpec文档显示了如何创建自定义匹配器(内联匹配器): http://phpspec.readthedocs.org/en/latest/cookbook/matchers.html#inline-matcher
我的ThingImTestingSpec
类中有这个内联匹配器(作为示例):
public function getMatchers()
{
return [
'haveSecondLevelKey' => function ($subject, $key) {
foreach ($subject as $first_level_key => $second_level_array)
{
if (is_array($second_level_array))
{
return array_key_exists($key, $second_level_array);
}
}
return FALSE;
}
];
}
此内联匹配器示例检测数组是否将数组作为其值之一,并返回true或false。
据我所知,PHPSpec在构建getMatchers()
时调用ThingImTestingSpec
,如果存在getMatchers()
方法(否则PHPSpec最终调用空getMatchers()
方法在ObjectBehavior
。
我尝试了什么:
创建一个CustomMatchers类并命名它:
namespace SpecUtilities;
class CustomMatchers
{
public static function getMatchers()
{ ... }
}
并将其添加到我的spec文件中:
use SpecUtilities\CustomMatchers
并且在班级本身:
function it_pulls_in_custom_matchers()
{
CustomMatchers::getMatchers();
}
但运行测试时getMatchers()
的返回不会被用于任何事情。 PHPSpec似乎只是在构造测试时使用getMatchers()
的返回值(这是有道理的 - getMatchers()
只返回一个函数数组;它不会将这些函数附加到其他任何函数上,因此PHPSpec不是不使用它们。我收到了错误
no haveSecondLevelKey([array:1]) matcher found for [array:14].
即。 PHPSpec未加载自定义匹配器。
所有规范类都扩展ObjectBehavior
。我可以将我的getMatchers()
函数添加到PHPSpec的ObjectBehavior
类,但我不想修改/ vendor下的文件(使用Composer引入PHPSpec)。我可以复制供应商文件并修改我自己的CustomObjectBehavior
类,并使我的规范类扩展它,但这会破坏PHPSpec的生成器方法的可用性,如phpspec describe SomeNewSpec
(我将不得不更改每次生成新规范时新规范都会扩展的类。)
我问得太多了吗?如果没有修改ObjectBehavior
本身来查找和加载外部自定义匹配器文件,并为PHPSpec repo本身提出拉取请求,是否有办法加载自定义匹配器而不会陷入不良做法?
答案 0 :(得分:1)
我为此目的使用了扩展程序"phpspec-matcher-loader-extension" - 它对我来说效果很好。从描述:
允许通过配置
全局注册自定义phpspec匹配器
答案 1 :(得分:0)
有两种方法可以获得所需的结果:
a)扩展ObjectBehaviour并添加新的默认getMatchers,然后扩展新的类而不是ObjectBehaviour。您可以使用自定义模板来确保describe
然后生成扩展正确对象的类(请参阅PhpSpec本身如何使用自定义模板https://github.com/phpspec/phpspec/tree/master/.phpspec)
b)将您的Matchers编写为实现PhpSpec\Matcher\MatcherInterface
的对象,然后编写一个扩展,用PhpSpec注册您的自定义匹配器。这更复杂,需要了解Matchers的注册方式。
我们正在考虑如何在将来的版本中使这更容易,可能通过一些配置设置。