【问题标题】:PHPSpec does not call the method of the subjectPHPSpec 不调用主题的方法
【发布时间】:2017-10-19 09:54:54
【问题描述】:

以下是我的phpspec代码

function it_throws_if_raw_data_xml_is_invalid()
{
    $website = $this->buildWebsite("some-deterministic-id", "some-deterministic-name");

    $this->convertAdwordsRawData($website, "yesterday", "invalidXML");

    $this->shouldThrow(AdwordsResponseNotParseable::class)
        ->during("convertAdwordsRawData", [$website, "yesterday", "invalid-xml"]);
}

测试失败,但不是因为逻辑错误,而是因为convertAdwordsRawData 永远不会被调用。我在其中添加了 var_dump 并且它没有显示出来,而构造函数的输出通过了。我尝试传递字符串而不是 $website,但遇到了类型提示问题。如果我只是在没有断言的情况下调用测试内部的方法,它永远不会调用该方法并通过测试,而不从 var_dump 输出任何内容。总而言之,phpspec 只是不为我执行该方法。它上面的一个测试,测试相同的公共方法,工作得很好。

这里可能有什么问题?

为了论证起见,考虑该方法执行以下操作

public function convertAdwordsRawData(Websites $website, string $time, string $rawData): \Generator
    {
        var_dump("Here I am");
        throw new AdwordsResponseNotParseable($rawData);
        yield from [1,2,3,4,5];
    }

更新 好的,这一切都归结为 php 如何处理生成器。方法调用将返回一个尚未初始化的迭代器。当我在实际返回的生成器上调用该方法时,PHP 将运行所有内容,直到第一次迭代的第一次产量,并在任何连续的迭代中返回产量。

来自 php.net 网站

当一个生成器函数第一次被调用时,一个对象 返回内部生成器类。这个对象实现了 迭代器接口

$this->convertAdwordsRawData(...)->shouldThrow(...)->duringCurrent();

是解决方案。 current() 调用来自于 PHP 中 Iterator 的实现——每次迭代都会调用这个方法

【问题讨论】:

  • 不看就很难发现函数内部出了什么问题。但是尝试在 xdebug 中设置断点,然后单步执行以找出问题所在。 XDebug 是一款非常快速、强大且有用的工具,可用于调试此类错误。
  • 感谢您的回复。问题不在于函数,问题在于 phpspec 本身。该方法根本不会被调用。我可以使用 xDebug 遍历 phpspec 的内部结构,但老实说我希望它不会出现这种情况

标签: php phpspec


【解决方案1】:

试试看:

function it_throws_if_raw_data_xml_is_invalid(Websites $website)
{
    $this->shouldThrow(AdwordsResponseNotParseable::class)
    ->during("convertAdwordsRawData", [$website, "yesterday", "invalid-xml"]);    

}

更多信息:http://www.phpspec.net/en/stable/cookbook/matchers.html#throw-matcher

【讨论】:

  • 这正是我所拥有的。显然问题是我对 PHP 如何处理迭代的理解不足,但我认为初始化代码(直到第一次产量)将被执行。但是 PHP 只在第一次迭代时这样做
猜你喜欢
  • 2013-06-16
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-15
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多