【问题标题】:How to create global custom matchers in PHPSpec?如何在 PHPSpec 中创建全局自定义匹配器?
【发布时间】:2016-01-28 23:30:30
【问题描述】:

我正在使用 PHPSpec 进行测试,并且我的规范文件中有自定义匹配器,我不想在使用它们的每个文件中重复。

我希望能够扩展 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。

据我所知,如果存在getMatchers() 方法,PHPSpec 在构造ThingImTestingSpec 时会调用getMatchers()(否则PHPSpec 最终会在ObjectBehavior 上调用空的getMatchers() 方法。

我尝试过的:

创建一个 CustomMatchers 类并为其命名:

namespace SpecUtilities;

class CustomMatchers
{
    public static function getMatchers()
    { ... }
}

并将其添加到我的规范文件中:

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 下的文件(PHPSpec 正在使用 Composer 引入)。我可以复制供应商文件并修改我自己的 CustomObjectBehavior 类,并让我的规范类扩展它,但这会破坏 PHPSpec 的生成器方法的可用性,如 phpspec describe SomeNewSpec(我将不得不更改新规范的类每次生成新规范时都扩展)。

我要求太多了吗?除了修改 ObjectBehavior 本身来查找和加载外部自定义匹配器文件,并对 PHPSpec 存储库本身发出拉取请求,有没有办法加载自定义匹配器而不会陷入不良实践?

【问题讨论】:

    标签: php unit-testing tdd phpspec


    【解决方案1】:

    为此,我使用了扩展名"phpspec-matcher-loader-extension"——它对我来说效果很好。来自描述:

    允许通过配置全局注册自定义 phpspec 匹配器

    【讨论】:

      【解决方案2】:

      有两种方法可以得到你想要的结果:

      a) 扩展 ObjectBehaviour 并添加一个新的默认 getMatchers,然后扩展您的新类而不是 ObjectBehaviour。您可以使用自定义模板来确保 describe 然后生成扩展正确对象的类(请参阅 PhpSpec 本身如何使用自定义模板 https://github.com/phpspec/phpspec/tree/master/.phpspec

      b) 将您的匹配器编写为实现PhpSpec\Matcher\MatcherInterface 的对象,然后编写一个扩展,将您的自定义匹配器注册到 PhpSpec。这比较复杂,需要了解 Matcher 的注册方式。

      我们正在考虑如何在未来的版本中使这更容易,也许通过一些配置设置。

      【讨论】:

      • 您能跟进一下吗?文档说您可以使用配置设置自动加载,但没有关于 如何 正确扩展 PhpSpec\Matcher\Matcher 的信息。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-31
      相关资源
      最近更新 更多