如何在 PHPSpec 中创建全局自定义匹配器?
How to create global custom matchers in PHPSpec?
我正在使用 PHPSpec 进行测试,我的规范文件中有自定义匹配器,我不想在使用它们的每个文件中都重复这些匹配器。
我希望能够扩展 PHPSpec 的行为 and/or 我所有测试的行为以使用一组全局自定义匹配器。
PHPSpec 文档显示了如何创建自定义匹配器(内联匹配器):
http://phpspec.readthedocs.org/en/latest/cookbook/matchers.html#inline-matcher
我的 ThingImTestingSpec
class:
中有这个内联匹配器(作为示例)
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;
}
];
}
这个内联匹配器示例检测一个数组是否有一个数组作为它的值之一,并且 return 是真还是假。
据我所知,PHPSpec 在构造 ThingImTestingSpec
时调用 getMatchers()
,如果存在 getMatchers()
方法(否则 PHPSpec 最终会调用空的 getMatchers()
ObjectBehavior
.
上的方法
我尝试过的:
创建一个 CustomMatchers class 并为其命名:
namespace SpecUtilities;
class CustomMatchers
{
public static function getMatchers()
{ ... }
}
并将其添加到我的规范文件中:
use SpecUtilities\CustomMatchers
并且在 class 本身:
function it_pulls_in_custom_matchers()
{
CustomMatchers::getMatchers();
}
但是 getMatchers()
中的 return 当测试为 运行 时不会用于任何事情。 PHPSpec 在构建测试时似乎只使用 getMatchers()
中的 return (这很有意义 - getMatchers()
只是 return 一个函数数组;它不附加这些函数用于其他任何东西,所以 PHPSpec 没有使用它们)。我收到错误
no haveSecondLevelKey([array:1]) matcher found for [array:14].
即PHPSpec 未加载自定义匹配器。
所有规范 class 扩展 ObjectBehavior
。我可以将我的 getMatchers()
函数添加到 PHPSpec 的 ObjectBehavior
class,但我不想修改 /vendor 下的文件(使用 Composer 引入 PHPSpec)。我可以复制供应商文件并修改我自己的 CustomObjectBehavior
class,并使我的规范 classes 扩展它,但这会破坏 PHPSpec 生成器方法的可用性,如 phpspec describe SomeNewSpec
(每次生成新规格时,我都必须更改新规格扩展的 class)。
我是不是要求太多了?除了修改 ObjectBehavior
本身以查找和加载外部自定义匹配器文件,并为 PHPSpec 存储库本身发出拉取请求外,是否有一种方法可以加载自定义匹配器而不会陷入不良做法?
有两种方法可以得到你想要的结果:
a) 扩展 ObjectBehaviour 并添加新的默认 getMatchers,然后扩展新的 class 而不是 ObjectBehaviour。您可以使用自定义模板来确保 describe
然后生成 classes 扩展正确的对象(查看 PhpSpec 本身如何使用自定义模板 https://github.com/phpspec/phpspec/tree/master/.phpspec)
b) 将您的匹配器编写为实现 PhpSpec\Matcher\MatcherInterface
的对象,然后编写一个扩展,将您的自定义匹配器注册到 PhpSpec。这比较复杂,需要了解 Matchers 的注册方式。
我们正在考虑如何在未来的版本中使这更容易,可能是通过一些配置设置。
为此,我使用了扩展程序 "phpspec-matcher-loader-extension" -- 它对我来说效果很好。来自描述:
Allows custom phpspec matchers to be registered globally via configuration
我正在使用 PHPSpec 进行测试,我的规范文件中有自定义匹配器,我不想在使用它们的每个文件中都重复这些匹配器。
我希望能够扩展 PHPSpec 的行为 and/or 我所有测试的行为以使用一组全局自定义匹配器。
PHPSpec 文档显示了如何创建自定义匹配器(内联匹配器): http://phpspec.readthedocs.org/en/latest/cookbook/matchers.html#inline-matcher
我的 ThingImTestingSpec
class:
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;
}
];
}
这个内联匹配器示例检测一个数组是否有一个数组作为它的值之一,并且 return 是真还是假。
据我所知,PHPSpec 在构造 ThingImTestingSpec
时调用 getMatchers()
,如果存在 getMatchers()
方法(否则 PHPSpec 最终会调用空的 getMatchers()
ObjectBehavior
.
我尝试过的:
创建一个 CustomMatchers class 并为其命名:
namespace SpecUtilities;
class CustomMatchers
{
public static function getMatchers()
{ ... }
}
并将其添加到我的规范文件中:
use SpecUtilities\CustomMatchers
并且在 class 本身:
function it_pulls_in_custom_matchers()
{
CustomMatchers::getMatchers();
}
但是 getMatchers()
中的 return 当测试为 运行 时不会用于任何事情。 PHPSpec 在构建测试时似乎只使用 getMatchers()
中的 return (这很有意义 - getMatchers()
只是 return 一个函数数组;它不附加这些函数用于其他任何东西,所以 PHPSpec 没有使用它们)。我收到错误
no haveSecondLevelKey([array:1]) matcher found for [array:14].
即PHPSpec 未加载自定义匹配器。
所有规范 class 扩展 ObjectBehavior
。我可以将我的 getMatchers()
函数添加到 PHPSpec 的 ObjectBehavior
class,但我不想修改 /vendor 下的文件(使用 Composer 引入 PHPSpec)。我可以复制供应商文件并修改我自己的 CustomObjectBehavior
class,并使我的规范 classes 扩展它,但这会破坏 PHPSpec 生成器方法的可用性,如 phpspec describe SomeNewSpec
(每次生成新规格时,我都必须更改新规格扩展的 class)。
我是不是要求太多了?除了修改 ObjectBehavior
本身以查找和加载外部自定义匹配器文件,并为 PHPSpec 存储库本身发出拉取请求外,是否有一种方法可以加载自定义匹配器而不会陷入不良做法?
有两种方法可以得到你想要的结果:
a) 扩展 ObjectBehaviour 并添加新的默认 getMatchers,然后扩展新的 class 而不是 ObjectBehaviour。您可以使用自定义模板来确保 describe
然后生成 classes 扩展正确的对象(查看 PhpSpec 本身如何使用自定义模板 https://github.com/phpspec/phpspec/tree/master/.phpspec)
b) 将您的匹配器编写为实现 PhpSpec\Matcher\MatcherInterface
的对象,然后编写一个扩展,将您的自定义匹配器注册到 PhpSpec。这比较复杂,需要了解 Matchers 的注册方式。
我们正在考虑如何在未来的版本中使这更容易,可能是通过一些配置设置。
为此,我使用了扩展程序 "phpspec-matcher-loader-extension" -- 它对我来说效果很好。来自描述:
Allows custom phpspec matchers to be registered globally via configuration