测试iterables PHPUnit中

测试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也。

希望这有助于

+0

如果你有一个'Traversable'并且只关心值yes,那么这个方法就行得通。但它不适用于'iterable',因为'iterator_to_array'只需要'Traversable'。 –

我认为你需要包裹可迭代第一。举个例子,对于可迭代可以在迭代花园中找到一个装饰命名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将替换具有重复键的条目,从而产生具有重复键的最后一个迭代值的数组。如果您还需要断言迭代键,则可能需要修饰或更改遍历方法。