以下是我的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并且它没有显示,而构造函数的输出通过。我试图传递字符串而不是$网站,并得到一个typehint问题。如果我只是在没有断言的情况下调用测试中的方法,它就不会调用方法并传递测试,而不会从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将运行所有内容直到第一次迭代的第一次生成,并在任何连续迭代时返回yield。
来自php.net网站
第一次调用生成器函数时,是一个对象 返回内部Generator类。该对象实现了 迭代器接口
$this->convertAdwordsRawData(...)->shouldThrow(...)->duringCurrent();
是解决方案。 current()调用来自PHP中Iterator的实现 - 每次迭代都会调用此方法
答案 0 :(得分:0)
试试:
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