测试iterables PHPUnit中
问题描述:
PHPUnit中它很容易断言,两个数组包含相同的值:测试iterables PHPUnit中
$this->assertEquals([1, 2, 3], [1, 2, 3]);
最新的PHP版本做迭代器和发电机很多更具吸引力的使用,以及PHP 7.1引入了the iterable pseudo-type。这意味着我可以编写函数来获取并返回iterable
,而不会与我使用简单的旧array
或使用懒惰Generator
的事实相结合。
如何声明返回iterable
函数的返回值?理想情况下我可以做类似
$this->assertIterablesEqual(['expected', 'values'], $iterable);
有没有这样的功能?或者,有没有一种合理的测试方法,不需要在我的测试中增加一堆除此之外的命令式代码?
答
你可以使用iterator_to_array功能,例如:
$expected = [1, 2, 3];
$this->assertEquals($expected, iterator_to_array($iterable));
这适用于generators也。
希望这有助于
答
我认为你需要包裹可迭代第一。举个例子,对于可迭代可以在迭代花园中找到一个装饰命名ForeachIterator这是decorating anything foreach-able作为Traversable的:
$iterator = new ForeachIterator($iterable);
$this->assertEquals([1, 2, 3], itarator_to_array($iterator));
注意为细节,它也会考虑对象可迭代该测试对于正确的测试来说不够严格。
但是这应该是很容易转化为测试私有辅助方法,只能求助于阵列和穿越的对象 - 不是非穿越的对象 - 到一个迭代器/阵列和应用断言:
private function assertIterablesEqual(array $expected, iterable $actual, $message = '')
{
$array = is_array($actual) ?: iterator_to_array($actual);
$this->assertEquals($expected, $array, $message);
}
这可以进一步extracted into an assertion class to extend Phpunit itself。
请注意,iterator_to_array
将替换具有重复键的条目,从而产生具有重复键的最后一个迭代值的数组。如果您还需要断言迭代键,则可能需要修饰或更改遍历方法。
如果你有一个'Traversable'并且只关心值yes,那么这个方法就行得通。但它不适用于'iterable',因为'iterator_to_array'只需要'Traversable'。 –